[tor-commits] [stem/master] Update OpenBSD package name

2021-12-31 Thread atagar
commit 4ead96c934838827b8339d780127ac78b15bd1ed
Author: Damian Johnson 
Date:   Fri Dec 31 14:51:13 2021 -0800

Update OpenBSD package name

Fix from nyxnor...

  https://github.com/torproject/stem/pull/113
---
 docs/download.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/download.rst b/docs/download.rst
index 8b528bbd..a524bd2a 100644
--- a/docs/download.rst
+++ b/docs/download.rst
@@ -213,7 +213,7 @@ Download
 
::
 
-   % pkg_add py-stem
+   % pkg_add py3-stem
 
* - .. image:: /_static/section/download/netbsd.png
   :target: http://pkgsrc.se/net/py-stem

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] nyxrc.sample: fix default for `graph_bound`

2021-11-18 Thread atagar
commit 096e51b67688c88168c0bc5d7af686b98013c1fb
Author: Alexander Batischev 
Date:   Tue Nov 9 14:27:10 2021 +0300

nyxrc.sample: fix default for `graph_bound`
---
 web/nyxrc.sample | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/web/nyxrc.sample b/web/nyxrc.sample
index 422c220..0851ac0 100644
--- a/web/nyxrc.sample
+++ b/web/nyxrc.sample
@@ -31,7 +31,7 @@ max_log_size 1000   # Maximum number of log entries.
 
 graph_stat bandwidth# Statistic to be graphed. [2]
 graph_interval each second  # Graph sampling interval. [3]
-graph_bound max_local   # Bounding for the graph min and max. [4]
+graph_bound local_max   # Bounding for the graph min and max. [4]
 graph_height 7  # Height of the graph.
 max_graph_width 300 # Maximum number of samplings.
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] nyxrc.sample: comment out options without defaults

2021-11-18 Thread atagar
commit 1cf449ce319757e0e7fa883c9ee725ca9c959a77
Author: Alexander Batischev 
Date:   Tue Nov 9 14:40:00 2021 +0300

nyxrc.sample: comment out options without defaults

This is a cosmetic change that prevents Nyx from complaining about
missing directories.
---
 web/nyxrc.sample | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/web/nyxrc.sample b/web/nyxrc.sample
index f69d165..422c220 100644
--- a/web/nyxrc.sample
+++ b/web/nyxrc.sample
@@ -1,5 +1,5 @@
 # Nyx can be customized through a configuration file with the following
-# options. Values shown below are the default unless marked with a asterisk.
+# options.
 #
 # Place your configuration at ~/.nyx/config or run with the following to
 # apply the settings...
@@ -8,7 +8,7 @@
 
 data_directory ~/.nyx   # Caching location, can be set to 'disabled'.
 password none   # Control port password of tor.
-tor_chroot /path# Chroot jail tor resides within if there is one. (*)
+#tor_chroot /path   # Chroot jail tor resides within if there is one.
 show_bits false # Bandwidth rate as bits if true, bytes otherwise.
 confirm_quit true   # Confirm before quitting.
 color_interface true# Uses color in our interface.
@@ -25,8 +25,8 @@ logged_events NOTICE, WARN, ERR, NYX_NOTICE, NYX_WARNING, 
NYX_ERROR
 # Events that are shown by default in the log.
 deduplicate_log true# Hides duplicate log messages.
 prepopulate_log true# Populates with events that occure before we started.
-logging_filter pattern  # Regex filter for log messages that are shown. (*)
-write_logs_to /path # Writes events that occure while running here. (*)
+#logging_filter pattern # Regex filter for log messages that are shown.
+#write_logs_to /path# Writes events that occure while running here.
 max_log_size 1000   # Maximum number of log entries.
 
 graph_stat bandwidth# Statistic to be graphed. [2]

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] nyxrc.sample: specify defaults inline

2021-11-18 Thread atagar
commit 61182a8961234acbde50a997568282023b0c797b
Author: Alexander Batischev 
Date:   Tue Nov 9 14:29:42 2021 +0300

nyxrc.sample: specify defaults inline

This allows the user to simply copy the config and start Nyx. Prior to
this commit, Nyx won't start in that case, because some of the settings
had placeholders instead of their actual defaults.
---
 web/nyxrc.sample | 33 -
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git a/web/nyxrc.sample b/web/nyxrc.sample
index bf0f787..f69d165 100644
--- a/web/nyxrc.sample
+++ b/web/nyxrc.sample
@@ -21,24 +21,25 @@ connection_rate 5   # Seconds between querying 
connections.
 resource_rate 5 # Seconds between querying process resource usage.
 port_usage_rate 5   # Seconds between querying processes using ports.
 
-logged_events events# Events that are shown by default in the log. [2]
+logged_events NOTICE, WARN, ERR, NYX_NOTICE, NYX_WARNING, NYX_ERROR
+# Events that are shown by default in the log.
 deduplicate_log true# Hides duplicate log messages.
 prepopulate_log true# Populates with events that occure before we started.
 logging_filter pattern  # Regex filter for log messages that are shown. (*)
 write_logs_to /path # Writes events that occure while running here. (*)
 max_log_size 1000   # Maximum number of log entries.
 
-graph_stat bandwidth# Statistic to be graphed. [3]
-graph_interval each second  # Graph sampling interval. [4]
-graph_bound max_local   # Bounding for the graph min and max. [5]
+graph_stat bandwidth# Statistic to be graphed. [2]
+graph_interval each second  # Graph sampling interval. [3]
+graph_bound max_local   # Bounding for the graph min and max. [4]
 graph_height 7  # Height of the graph.
 max_graph_width 300 # Maximum number of samplings.
 
-config_order order  # Order for tor config options. [6]
+config_order MAN_PAGE_ENTRY, NAME, IS_SET # Order for tor config options. [5]
 show_private_options false  # Shows configurations with a '__option' prefix.
 show_virtual_options false  # Shows unsettable tor configurations.
 
-connection_order order  # Order for connections. [7]
+connection_order CATEGORY, IP_ADDRESS, UPTIME # Order for connections. [6]
 resolve_processes true  # Shows processes for SOCKS and CONTROL connections.
 show_addresses true # Shows addresses of connections.
 
@@ -55,31 +56,25 @@ show_interpreter true   # Shows the control interpreter.
 #
 #   'none" means "use the default color that the developers picked".
 #
-#   Default is: none
-#
-# [2] logged_events is a comma separated list. Default value is...
-#
-#   NOTICE, WARN, ERR, NYX_NOTICE, NYX_WARNING, NYX_ERROR
-#
-# [3] graph_stat options include...
+# [2] graph_stat options include...
 #
 #   none - hide the graph
 #   bandwidth - bandwidth rate downloaded/uploaded
 #   connections- number of connections inbound/outbound
 #   resources - cpu/memory usage of tor
 #
-# [4] graph_interval options include...
+# [3] graph_interval options include...
 #
 #   each second,   5 seconds, 30 seconds,  minutely,
 #   15 minute, 30 minute, hourly,  daily
 #
-# [5] graph_bound options include...
+# [4] graph_bound options include...
 #
 #   global_max - global maximum (highest value ever seen)
 #   local_max - local maximum (highest value currently on the graph)
 #   tight - local maximum and minimum
 #
-# [6] config_order is three comma separated values that can include...
+# [5] config_order is three comma separated values that can include...
 #
 #   * NAME
 #   * VALUE
@@ -91,9 +86,7 @@ show_interpreter true   # Shows the control interpreter.
 #   * MAN_PAGE_ENTRY
 #   * IS_SET
 #
-# Default is: MAN_PAGE_ENTRY, NAME, IS_SET
-#
-# [7] connection_order is three comma separated values that can include...
+# [6] connection_order is three comma separated values that can include...
 #
 #   * CATEGORY
 #   * UPTIME
@@ -102,5 +95,3 @@ show_interpreter true   # Shows the control interpreter.
 #   * FINGERPRINT
 #   * NICKNAME
 #   * COUNTRY
-#
-# Default is: CATEGORY, IP_ADDRESS, UPTIME

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Make exit_used.py compatible with asyncio

2021-11-18 Thread atagar
commit 7e9ea4dbb80e81d2a977937ccfca57bb41e20270
Author: Damian Johnson 
Date:   Thu Nov 18 13:42:22 2021 -0800

Make exit_used.py compatible with asyncio

Honestly this is probably somewhat a step backward because if I return to 
Stem
I plan to substantially revert the asyncio migration, but for now simply 
fixing
the script. With the current codebase it fails with...

  % python exit_used.py
  Tracking requests for tor exits. Press 'enter' to end.

  stem/stem/control.py:4004: RuntimeWarning: coroutine 
'Controller.get_circuit' was never awaited
log.warn('Event listener raised an uncaught exception (%s): %s' % (exc, 
event))
---
 docs/_static/example/exit_used.py | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/docs/_static/example/exit_used.py 
b/docs/_static/example/exit_used.py
index 296b0864..4462620e 100644
--- a/docs/_static/example/exit_used.py
+++ b/docs/_static/example/exit_used.py
@@ -17,18 +17,18 @@ def main():
 input()  # wait for user to press enter
 
 
-def stream_event(controller, event):
+async def stream_event(controller, event):
   if event.status == StreamStatus.SUCCEEDED and event.circ_id:
-circ = controller.get_circuit(event.circ_id)
+circ = await controller.get_circuit(event.circ_id)
 
 exit_fingerprint = circ.path[-1][0]
-exit_relay = controller.get_network_status(exit_fingerprint)
+exit_relay = await controller.get_network_status(exit_fingerprint)
 
 print('Exit relay for our connection to %s' % (event.target))
 print('  address: %s:%i' % (exit_relay.address, exit_relay.or_port))
 print('  fingerprint: %s' % exit_relay.fingerprint)
 print('  nickname: %s' % exit_relay.nickname)
-print('  locale: %s' % controller.get_info('ip-to-country/%s' % 
exit_relay.address, 'unknown'))
+print('  locale: %s' % (await controller.get_info('ip-to-country/%s' % 
exit_relay.address), 'unknown'))
 print('')
 
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Skip internal circuits in exit_used.py example

2021-11-18 Thread atagar
commit 57364fae7269ec562c5fc8cdb073ff9463d9a0f0
Author: Damian Johnson 
Date:   Thu Nov 18 14:00:32 2021 -0800

Skip internal circuits in exit_used.py example

pragma31 made the good point that exit_used.py confusingly presents the
internal 1-hop circuits for fetching descriptors. Filtering those out.

  https://github.com/torproject/stem/pull/111
---
 docs/_static/example/exit_used.py | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/docs/_static/example/exit_used.py 
b/docs/_static/example/exit_used.py
index 4462620e..405425e4 100644
--- a/docs/_static/example/exit_used.py
+++ b/docs/_static/example/exit_used.py
@@ -1,6 +1,6 @@
 import functools
 
-from stem import StreamStatus
+from stem import CircBuildFlag, StreamStatus
 from stem.control import EventType, Controller
 
 
@@ -21,6 +21,9 @@ async def stream_event(controller, event):
   if event.status == StreamStatus.SUCCEEDED and event.circ_id:
 circ = await controller.get_circuit(event.circ_id)
 
+if CircBuildFlag.IS_INTERNAL in circ.build_flags:
+  return
+
 exit_fingerprint = circ.path[-1][0]
 exit_relay = await controller.get_network_status(exit_fingerprint)
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] Clarify what `color_override none` means

2021-11-09 Thread atagar
commit 3e3b3323e7fa4edd8e4259d788d7cb5964cc4029
Author: Alexander Batischev 
Date:   Tue Nov 9 14:23:23 2021 +0300

Clarify what `color_override none` means

Cf. #39.
---
 web/index.html   |  2 +-
 web/nyxrc.sample | 35 +--
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/web/index.html b/web/index.html
index 7ef511b..98381e7 100644
--- a/web/index.html
+++ b/web/index.html
@@ -544,7 +544,7 @@ logged_events BW, NOTICE, WARN, ERR
 
   color_override
   
-  Replaces most color with this hue. Options available are 
red, green, blue, cyan, magenta, 
yellow, and black.
+  Replaces most color with this hue. Options available are 
red, green, blue, cyan, magenta, 
yellow, black, and none. The latter means that no colors 
are replaced, and so the default one is used.
 
 
 
diff --git a/web/nyxrc.sample b/web/nyxrc.sample
index 47bdba6..bf0f787 100644
--- a/web/nyxrc.sample
+++ b/web/nyxrc.sample
@@ -12,7 +12,7 @@ tor_chroot /path# Chroot jail tor resides within if 
there is one. (*)
 show_bits false # Bandwidth rate as bits if true, bytes otherwise.
 confirm_quit true   # Confirm before quitting.
 color_interface true# Uses color in our interface.
-color_override none # Replaces instances of color with this hue.
+color_override none # Replaces instances of color with this hue. [1]
 unicode_support true# Render text as unicode.
 acs_support true# Uses ACS (alternate character set) for nice borders.
 
@@ -21,24 +21,24 @@ connection_rate 5   # Seconds between querying 
connections.
 resource_rate 5 # Seconds between querying process resource usage.
 port_usage_rate 5   # Seconds between querying processes using ports.
 
-logged_events events# Events that are shown by default in the log. [1]
+logged_events events# Events that are shown by default in the log. [2]
 deduplicate_log true# Hides duplicate log messages.
 prepopulate_log true# Populates with events that occure before we started.
 logging_filter pattern  # Regex filter for log messages that are shown. (*)
 write_logs_to /path # Writes events that occure while running here. (*)
 max_log_size 1000   # Maximum number of log entries.
 
-graph_stat bandwidth# Statistic to be graphed. [2]
-graph_interval each second  # Graph sampling interval. [3]
-graph_bound max_local   # Bounding for the graph min and max. [4]
+graph_stat bandwidth# Statistic to be graphed. [3]
+graph_interval each second  # Graph sampling interval. [4]
+graph_bound max_local   # Bounding for the graph min and max. [5]
 graph_height 7  # Height of the graph.
 max_graph_width 300 # Maximum number of samplings.
 
-config_order order  # Order for tor config options. [5]
+config_order order  # Order for tor config options. [6]
 show_private_options false  # Shows configurations with a '__option' prefix.
 show_virtual_options false  # Shows unsettable tor configurations.
 
-connection_order order  # Order for connections. [6]
+connection_order order  # Order for connections. [7]
 resolve_processes true  # Shows processes for SOCKS and CONTROL connections.
 show_addresses true # Shows addresses of connections.
 
@@ -49,30 +49,37 @@ show_connections true   # Shows connection information.
 show_config true# Shows tor's configuration.
 show_torrc true # Shows the torrc.
 show_interpreter true   # Shows the control interpreter.
-
-# [1] logged_events is a comma separated list. Default value is...
+# [1] color_override options include...
+#
+#   none, red, green, blue, cyan, magenta, yellow, black
+#
+#   'none" means "use the default color that the developers picked".
+#
+#   Default is: none
+#
+# [2] logged_events is a comma separated list. Default value is...
 #
 #   NOTICE, WARN, ERR, NYX_NOTICE, NYX_WARNING, NYX_ERROR
 #
-# [2] graph_stat options include...
+# [3] graph_stat options include...
 #
 #   none - hide the graph
 #   bandwidth - bandwidth rate downloaded/uploaded
 #   connections- number of connections inbound/outbound
 #   resources - cpu/memory usage of tor
 #
-# [3] graph_interval options include...
+# [4] graph_interval options include...
 #
 #   each second,   5 seconds, 30 seconds,  minutely,
 #   15 minute, 30 minute, hourly,  daily
 #
-# [4] graph_bound options include...
+# [5] graph_bound options include...
 #
 #   global_max - global maximum (highest value ever seen)
 #   local_max - local maximum (highest value currently on the graph)
 #   tight - local maximum and minimum
 #
-# [5] config_order is three comma separated values that can include...
+# [6] config_order is three comma separated values that can include...
 #
 #   * NAME
 #   * VALUE
@@ -86,7 +93,7 @@ show_interpreter true   # Shows the control interpreter.
 #
 # 

[tor-commits] [stem/master] Fixup for Python 3.10

2021-11-08 Thread atagar
commit 36bcb170ba9097885902513640075eac2e6ce384
Author: Calin Culianu 
Date:   Mon Nov 8 18:15:59 2021 -0600

Fixup for Python 3.10

Closes issue #109.  Long story short: a few names from collection are
now moved to collection.abc exclusively starting in Python 3.10. The
only name this app uses from there that was moved is
`collections.Iterable`.  Python versions starting from 3.3 support both
`collections.Iterable` and `collections.abc.Iterable` as the way to refer to
this class, which Python 3.10 being the first one to drop
`collections.Iterable`.  So.. we just work around this API quirk
and always refer ot it as `collections.abc.Iterable`.
---
 stem/control.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/stem/control.py b/stem/control.py
index 40ca6bed..159b2046 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -247,6 +247,7 @@ If you're fine with allowing your script to raise 
exceptions then this can be mo
 import asyncio
 import calendar
 import collections
+import collections.abc
 import datetime
 import functools
 import inspect
@@ -2496,7 +2497,7 @@ class Controller(BaseController):
 for param, value in params_list:
   if isinstance(value, str):
 query_comp.append('%s="%s"' % (param, value.strip()))
-  elif isinstance(value, collections.Iterable):
+  elif isinstance(value, collections.abc.Iterable):
 query_comp.extend(['%s="%s"' % (param, val.strip()) for val in value])
   elif not value:
 query_comp.append(param)

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Add timezone to parsed datetimes

2021-10-26 Thread atagar
commit f8717b4bffd46c8c0ee7147f5b50927737b2b5e1
Author: Steven Engler 
Date:   Mon Oct 25 14:46:39 2021 -0400

Add timezone to parsed datetimes
---
 stem/control.py |  3 ++-
 stem/descriptor/__init__.py |  3 ++-
 stem/descriptor/extrainfo_descriptor.py |  2 +-
 stem/descriptor/networkstatus.py|  2 +-
 stem/descriptor/router_status_entry.py  |  3 ++-
 stem/descriptor/tordnsel.py |  6 +++---
 stem/response/events.py |  8 +---
 stem/util/str_tools.py  | 15 +++
 8 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/stem/control.py b/stem/control.py
index e162704b..40ca6bed 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -247,6 +247,7 @@ If you're fine with allowing your script to raise 
exceptions then this can be mo
 import asyncio
 import calendar
 import collections
+import datetime
 import functools
 import inspect
 import io
@@ -1537,7 +1538,7 @@ class Controller(BaseController):
   self.get_info('accounting/bytes-left'),
 )
 
-interval_end = stem.util.str_tools._parse_timestamp(interval_end)
+interval_end = stem.util.str_tools._parse_timestamp(interval_end, 
datetime.timezone.utc)
 used_read, used_written = [int(val) for val in used.split(' ', 1)]
 left_read, left_written = [int(val) for val in left.split(' ', 1)]
 
diff --git a/stem/descriptor/__init__.py b/stem/descriptor/__init__.py
index c015d246..d928ff21 100644
--- a/stem/descriptor/__init__.py
+++ b/stem/descriptor/__init__.py
@@ -108,6 +108,7 @@ import base64
 import codecs
 import collections
 import copy
+import datetime
 import hashlib
 import io
 import os
@@ -683,7 +684,7 @@ def _parse_timestamp_line(keyword: str, attribute: str) -> 
Callable[['stem.descr
 value = _value(keyword, entries)
 
 try:
-  setattr(descriptor, attribute, 
stem.util.str_tools._parse_timestamp(value))
+  setattr(descriptor, attribute, 
stem.util.str_tools._parse_timestamp(value, datetime.timezone.utc))
 except ValueError:
   raise ValueError("Timestamp on %s line wasn't parsable: %s %s" % 
(keyword, keyword, value))
 
diff --git a/stem/descriptor/extrainfo_descriptor.py 
b/stem/descriptor/extrainfo_descriptor.py
index 8d9cbf30..ad08d361 100644
--- a/stem/descriptor/extrainfo_descriptor.py
+++ b/stem/descriptor/extrainfo_descriptor.py
@@ -239,7 +239,7 @@ def _parse_timestamp_and_interval(keyword: str, content: 
str) -> Tuple[datetime.
 raise ValueError("%s line's interval wasn't a number: %s" % (keyword, 
line))
 
   try:
-timestamp = stem.util.str_tools._parse_timestamp(timestamp_str)
+timestamp = stem.util.str_tools._parse_timestamp(timestamp_str, 
datetime.timezone.utc)
 return timestamp, int(interval), remainder
   except ValueError:
 raise ValueError("%s line's timestamp wasn't parsable: %s" % (keyword, 
line))
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index e8cf90eb..a69f501f 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -1962,7 +1962,7 @@ class BridgeNetworkStatusDocument(NetworkStatusDocument):
   published_line = published_line.split(' ', 1)[1].strip()
 
   try:
-self.published = stem.util.str_tools._parse_timestamp(published_line)
+self.published = stem.util.str_tools._parse_timestamp(published_line, 
datetime.timezone.utc)
   except ValueError:
 if validate:
   raise ValueError("Bridge network status document's 'published' time 
wasn't parsable: %s" % published_line)
diff --git a/stem/descriptor/router_status_entry.py 
b/stem/descriptor/router_status_entry.py
index aa94a703..eed34fac 100644
--- a/stem/descriptor/router_status_entry.py
+++ b/stem/descriptor/router_status_entry.py
@@ -22,6 +22,7 @@ sources...
 """
 
 import binascii
+import datetime
 import io
 
 import stem.exit_policy
@@ -161,7 +162,7 @@ def _parse_r_line(descriptor: 'stem.descriptor.Descriptor', 
entries: ENTRY_TYPE)
 
   try:
 published = '%s %s' % (r_comp[3], r_comp[4])
-descriptor.published = stem.util.str_tools._parse_timestamp(published)
+descriptor.published = stem.util.str_tools._parse_timestamp(published, 
datetime.timezone.utc)
   except ValueError:
 raise ValueError("Publication time time wasn't parsable: r %s" % value)
 
diff --git a/stem/descriptor/tordnsel.py b/stem/descriptor/tordnsel.py
index 32cf1863..ffb67578 100644
--- a/stem/descriptor/tordnsel.py
+++ b/stem/descriptor/tordnsel.py
@@ -98,13 +98,13 @@ class TorDNSEL(Descriptor):
 self.fingerprint = value
   elif keyword == 'Published':
 try:
-  self.published = stem.util.str_tools._parse_timestamp(value)
+  self.published = stem.util.str_tools._parse_timestamp(value, 
datetime.timezone.utc)
 except ValueError:
   if validate:
 raise ValueError("Published time wasn't parsable: %s" % value)
   elif keyword == 'LastStatus':
   

[tor-commits] [stem/master] Update to python 3.9

2021-10-26 Thread atagar
commit 56f3daa4c124dae3e050b76d531480f8e233cc59
Author: Linus Gasser 
Date:   Fri Oct 22 10:12:06 2021 +0200

Update to python 3.9

Closes #105

Since python 3.2: 
https://docs.python.org/3/library/stdtypes.html#int.from_bytes
---
 stem/descriptor/__init__.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/stem/descriptor/__init__.py b/stem/descriptor/__init__.py
index 3f10bc57..c015d246 100644
--- a/stem/descriptor/__init__.py
+++ b/stem/descriptor/__init__.py
@@ -1051,7 +1051,7 @@ class Descriptor(object):
 try:
   from cryptography.hazmat.backends import default_backend
   from cryptography.hazmat.primitives.serialization import 
load_der_public_key
-  from cryptography.utils import int_to_bytes, int_from_bytes
+  from cryptography.utils import int_to_bytes
 except ImportError:
   raise ValueError('Generating the signed digest requires the cryptography 
module')
 
@@ -1060,7 +1060,7 @@ class Descriptor(object):
 public_exponent = key.public_numbers().e
 
 sig_as_bytes = _bytes_for_block(signature)
-sig_as_long = int_from_bytes(sig_as_bytes, byteorder='big')  # convert 
signature to an int
+sig_as_long = int.from_bytes(sig_as_bytes, byteorder='big')  # convert 
signature to an int
 blocksize = len(sig_as_bytes)  # 256B for NetworkStatusDocuments, 128B for 
others
 
 # use the public exponent[e] & the modulus[n] to decrypt the int

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Add socks creds into StreamEvent

2021-06-12 Thread atagar
commit 51515edf95ebea92ec93269b035439b84d59c627
Author: proukornew 
Date:   Sun Jun 13 01:24:35 2021 +0300

Add socks creds into StreamEvent

Slightly modified from https://github.com/torproject/stem/pull/101
---
 stem/response/events.py | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/stem/response/events.py b/stem/response/events.py
index d9d46d6a..2b9b6dfd 100644
--- a/stem/response/events.py
+++ b/stem/response/events.py
@@ -1081,6 +1081,8 @@ class StreamEvent(Event):
   :var str source_address: requester address (ip or hostname)
   :var int source_port: requester port
   :var stem.StreamPurpose purpose: purpose for the stream
+  :var str socks_username: username used by the socket connection
+  :var str socks_password: password used by the socket connection
   """
 
   _POSITIONAL_ARGS = ('id', 'status', 'circ_id', 'target')
@@ -1090,6 +1092,8 @@ class StreamEvent(Event):
 'SOURCE': 'source',
 'SOURCE_ADDR': 'source_addr',
 'PURPOSE': 'purpose',
+'SOCKS_USERNAME': 'socks_username',
+'SOCKS_PASSWORD': 'socks_password',
   }
 
   def __init__(self):
@@ -1106,6 +1110,8 @@ class StreamEvent(Event):
 self.source_address = None  # type: Optional[str]
 self.source_port = None  # type: Optional[str]
 self.purpose = None  # type: Optional[stem.StreamPurpose]
+self.socks_username = None  # type: Optional[str]
+self.socks_password = None  # type: Optional[str]
 
   def _parse(self) -> None:
 if self.target is None:

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Adds ClientAuthV3 support to the controller, for setting Client Auth with ADD_ONION on v3 onions

2021-05-05 Thread atagar
commit 2f3bbf64b4ce3b63160a3c56b15748ba626de4a0
Author: Miguel Jacq 
Date:   Wed May 5 11:50:47 2021 +1000

Adds ClientAuthV3 support to the controller, for setting Client Auth with 
ADD_ONION on v3 onions
---
 stem/control.py  | 25 +++
 stem/version.py  | 18 +
 test/integ/control/controller.py | 43 +++-
 test/require.py  | 10 ++
 4 files changed, 83 insertions(+), 13 deletions(-)

diff --git a/stem/control.py b/stem/control.py
index 91d1b3ed..f1b4f3f7 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -2889,7 +2889,7 @@ class Controller(BaseController):
 
 return [r for r in result if r]  # drop any empty responses (GETINFO is 
blank if unset)
 
-  async def create_ephemeral_hidden_service(self, ports: Union[int, 
Sequence[int], Mapping[int, str]], key_type: str = 'NEW', key_content: str = 
'BEST', discard_key: bool = False, detached: bool = False, await_publication: 
bool = False, timeout: Optional[float] = None, basic_auth: 
Optional[Mapping[str, str]] = None, max_streams: Optional[int] = None) -> 
stem.response.add_onion.AddOnionResponse:
+  async def create_ephemeral_hidden_service(self, ports: Union[int, 
Sequence[int], Mapping[int, str]], key_type: str = 'NEW', key_content: str = 
'BEST', discard_key: bool = False, detached: bool = False, await_publication: 
bool = False, timeout: Optional[float] = None, basic_auth: 
Optional[Mapping[str, str]] = None, max_streams: Optional[int] = None, 
client_auth_v3: Optional[str] = None) -> 
stem.response.add_onion.AddOnionResponse:
 """
 Creates a new hidden service. Unlike
 :func:`~stem.control.Controller.create_hidden_service` this style of
@@ -2940,8 +2940,10 @@ class Controller(BaseController):
   })
 
 Please note that **basic_auth** only works for legacy (v2) hidden services.
-Version 3 can't enable service authentication through the control protocol
-(:ticket:`tor-40084`).
+
+To use client auth with a **version 3** service, pass the 
**client_auth_v3**
+argument. The value must be a base32-encoded public key from a key pair you
+have generated elsewhere.
 
 To create a **version 3** service simply specify **ED25519-V3** as the
 our key type, and to create a **version 2** service use **RSA1024**. The
@@ -2958,6 +2960,7 @@ class Controller(BaseController):
 
   print('service established at %s.onion' % response.service_id)
 
+
 .. versionadded:: 1.4.0
 
 .. versionchanged:: 1.5.0
@@ -2971,6 +2974,9 @@ class Controller(BaseController):
 .. versionchanged:: 1.7.0
Added the timeout and max_streams arguments.
 
+.. versionchanged:: 2.0.0
+   Added the client_auth_v3 argument.
+
 :param ports: hidden service port(s) or mapping of hidden
   service ports to their targets
 :param key_type: type of key being provided, generates a new key if
@@ -2984,9 +2990,11 @@ class Controller(BaseController):
 :param await_publication: blocks until our descriptor is successfully
   published if **True**
 :param timeout: seconds to wait when **await_result** is **True**
-:param basic_auth: required user credentials to access this service
+:param basic_auth: required user credentials to access a v2 service
 :param max_streams: maximum number of streams the hidden service will
   accept, unlimited if zero or not set
+:param str client_auth_v3: base32-encoded public key for **version 3**
+  onion services that require client authentication
 
 :returns: :class:`~stem.response.add_onion.AddOnionResponse` with the 
response
 
@@ -3024,6 +3032,12 @@ class Controller(BaseController):
 if (await self.get_conf('HiddenServiceSingleHopMode', None)) == '1' and 
(await self.get_conf('HiddenServiceNonAnonymousMode', None)) == '1':
   flags.append('NonAnonymous')
 
+if client_auth_v3 is not None:
+  if await self.get_version() < 
stem.version.Requirement.ONION_SERVICE_AUTH_ADD:
+raise stem.UnsatisfiableRequest(message = 'Client authentication 
support for v3 onions was added to ADD_ONION in tor version %s' % 
stem.version.Requirement.ONION_SERVICE_AUTH_ADD)
+
+  flags.append('V3Auth')
+
 if flags:
   request += ' Flags=%s' % ','.join(flags)
 
@@ -3048,6 +3062,9 @@ class Controller(BaseController):
 else:
   request += ' ClientAuth=%s' % client_name
 
+if client_auth_v3 is not None:
+  request += ' ClientAuthV3=%s' % client_auth_v3
+
 response = 
stem.response._convert_to_add_onion(stem.response._convert_to_add_onion(await 
self.msg(request)))
 
 if await_publication:
diff --git a/stem/version.py b/stem/version.py
index 6edf93ae..2ca78245 100644
--- a/stem/version.py
+++ b/stem/version.py
@@ -26,14 +26,15 @@ easily parsed and compared, for instance...
 
   Enumerations for the version requirements of features.
 
-  === ===
-  

[tor-commits] [stem/master] Remove unintended whitespace

2021-05-05 Thread atagar
commit faab143a3ebe6dddc9c7bed08bfd00eed14ae0f0
Author: Miguel Jacq 
Date:   Wed May 5 12:06:13 2021 +1000

Remove unintended whitespace
---
 stem/control.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/stem/control.py b/stem/control.py
index f1b4f3f7..e162704b 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -2960,7 +2960,6 @@ class Controller(BaseController):
 
   print('service established at %s.onion' % response.service_id)
 
-
 .. versionadded:: 1.4.0
 
 .. versionchanged:: 1.5.0

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Adjust extended v3 HS address validation

2021-02-09 Thread atagar
commit 63a476056017dda5ede35efc4e4f7acfcc1d7d1a
Author: Damian Johnson 
Date:   Tue Feb 9 16:12:36 2021 -0800

Adjust extended v3 HS address validation

Mostly minor stylistic adjustments. The only functional bit is correcting a
unit test failure...


==
FAIL: test_identity_key_from_address

--
ValueError: 
'.onion' isn't a valid 
hidden service v3 address

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File 
"/home/atagar/Desktop/stem/test/unit/descriptor/hidden_service_v3.py", line 
220, in test_identity_key_from_address
self.assertRaisesWith(ValueError, 'Bad checksum (expected def7 but 
was 842e)', HiddenServiceDescriptorV3.identity_key_from_address, '5' * 56)
File "/home/atagar/Desktop/stem/stem/util/test_tools.py", line 249, 
in assertRaisesWith
return self.assertRaisesRegexp(exc_type, '^%s$' % 
re.escape(exc_msg), *args, **kwargs)
AssertionError: "^Bad\ checksum\ \(expected\ def7\ but\ was\ 
842e\)$" does not match 
"'.onion' isn't a valid 
hidden service v3 address"

--
---
 stem/descriptor/hidden_service.py |  2 +-
 stem/util/tor_tools.py| 35 +
 test/unit/util/tor_tools.py   | 46 ++-
 3 files changed, 37 insertions(+), 46 deletions(-)

diff --git a/stem/descriptor/hidden_service.py 
b/stem/descriptor/hidden_service.py
index 63f107e7..249c2153 100644
--- a/stem/descriptor/hidden_service.py
+++ b/stem/descriptor/hidden_service.py
@@ -1129,7 +1129,7 @@ class HiddenServiceDescriptorV3(HiddenServiceDescriptor):
 if onion_address.endswith('.onion'):
   onion_address = onion_address[:-6]
 
-if not stem.util.tor_tools.is_valid_hidden_service_address(onion_address, 
version = 3):
+if not stem.util.tor_tools.HS_V3_ADDRESS_PATTERN.match(onion_address):
   raise ValueError("'%s.onion' isn't a valid hidden service v3 address" % 
onion_address)
 
 # onion_address = base32(PUBKEY | CHECKSUM | VERSION) + '.onion'
diff --git a/stem/util/tor_tools.py b/stem/util/tor_tools.py
index c9a04e33..e758b897 100644
--- a/stem/util/tor_tools.py
+++ b/stem/util/tor_tools.py
@@ -19,9 +19,9 @@ Miscellaneous utility functions for working with tor.
   is_hex_digits - checks if a string is only made up of hex digits
 """
 
+import base64
+import hashlib
 import re
-from base64 import b32decode
-from hashlib import sha3_256
 
 import stem.util.str_tools
 
@@ -47,7 +47,6 @@ CIRC_ID_PATTERN = re.compile('^[a-zA-Z0-9]{1,16}$')
 
 HS_V2_ADDRESS_PATTERN = re.compile('^[a-z2-7]{16}$')
 HS_V3_ADDRESS_PATTERN = re.compile('^[a-z2-7]{56}$')
-HS_V3_CHECKSUM_CONSTANT = ".onion checksum"
 
 
 def is_valid_fingerprint(entry: str, check_prefix: bool = False) -> bool:
@@ -156,14 +155,6 @@ def is_valid_hidden_service_address(entry: str, version: 
Optional[Union[int, Seq
 otherwise
   """
 
-  def _extract_v3_parts(address):
-decoded = b32decode(address.upper())
-return (decoded[:32], decoded[32:34])
-
-  v3_pubkey = None
-  v3_checksum = None
-  v3_version = int(3).to_bytes(1, 'little')
-
   if isinstance(entry, bytes):
 entry = stem.util.str_tools._to_unicode(entry)
 
@@ -179,15 +170,19 @@ def is_valid_hidden_service_address(entry: str, version: 
Optional[Union[int, Seq
   return True
 
 if 3 in version and bool(HS_V3_ADDRESS_PATTERN.match(entry)):
-  # v3+ onions have a consistent version at end of address
-  if not entry.endswith('d'):
-return False
-  # Test that the checksum (part of every v3 address) is valid
-  v3_pubkey, v3_checksum = _extract_v3_parts(entry)
-  expected_checksum = sha3_256(HS_V3_CHECKSUM_CONSTANT.encode('utf-8') + 
v3_pubkey + v3_version).digest()[:2]
-  if expected_checksum != v3_checksum:
-return False
-  return True
+  # onion_address = base32(PUBKEY | CHECKSUM | VERSION) + ".onion"
+
+  decoded = base64.b32decode(entry.upper())
+  pubkey, checksum, addr_version = decoded[:32], decoded[32:34], 
decoded[34:]
+
+  if addr_version != b'\x03':
+return False  # VERSION component must be three
+
+  # CHECKSUM = H(".onion checksum" | PUBKEY | VERSION)[:2]
+
+  expected_checksum = hashlib.sha3_256(b'.onion checksum' + pubkey + 
addr_version).digest()[:2]
+
+  return checksum == expected_checksum
 
 return False
   except TypeError:
diff --git a/test/unit/util/tor_tools.py b/t

[tor-commits] [stem/master] Now validate Tor v3 address checksum in hidden service address validator

2021-02-09 Thread atagar
commit 434638a828201c286e5fef158761dc2c4c67e47d
Author: Kevin Froman 
Date:   Fri Feb 5 23:31:32 2021 +

Now validate Tor v3 address checksum in hidden service address validator
---
 stem/util/tor_tools.py  | 19 
 test/unit/util/tor_tools.py | 55 +
 2 files changed, 74 insertions(+)

diff --git a/stem/util/tor_tools.py b/stem/util/tor_tools.py
index e2df4312..c9a04e33 100644
--- a/stem/util/tor_tools.py
+++ b/stem/util/tor_tools.py
@@ -20,6 +20,8 @@ Miscellaneous utility functions for working with tor.
 """
 
 import re
+from base64 import b32decode
+from hashlib import sha3_256
 
 import stem.util.str_tools
 
@@ -45,6 +47,7 @@ CIRC_ID_PATTERN = re.compile('^[a-zA-Z0-9]{1,16}$')
 
 HS_V2_ADDRESS_PATTERN = re.compile('^[a-z2-7]{16}$')
 HS_V3_ADDRESS_PATTERN = re.compile('^[a-z2-7]{56}$')
+HS_V3_CHECKSUM_CONSTANT = ".onion checksum"
 
 
 def is_valid_fingerprint(entry: str, check_prefix: bool = False) -> bool:
@@ -153,6 +156,14 @@ def is_valid_hidden_service_address(entry: str, version: 
Optional[Union[int, Seq
 otherwise
   """
 
+  def _extract_v3_parts(address):
+decoded = b32decode(address.upper())
+return (decoded[:32], decoded[32:34])
+
+  v3_pubkey = None
+  v3_checksum = None
+  v3_version = int(3).to_bytes(1, 'little')
+
   if isinstance(entry, bytes):
 entry = stem.util.str_tools._to_unicode(entry)
 
@@ -168,6 +179,14 @@ def is_valid_hidden_service_address(entry: str, version: 
Optional[Union[int, Seq
   return True
 
 if 3 in version and bool(HS_V3_ADDRESS_PATTERN.match(entry)):
+  # v3+ onions have a consistent version at end of address
+  if not entry.endswith('d'):
+return False
+  # Test that the checksum (part of every v3 address) is valid
+  v3_pubkey, v3_checksum = _extract_v3_parts(entry)
+  expected_checksum = sha3_256(HS_V3_CHECKSUM_CONSTANT.encode('utf-8') + 
v3_pubkey + v3_version).digest()[:2]
+  if expected_checksum != v3_checksum:
+return False
   return True
 
 return False
diff --git a/test/unit/util/tor_tools.py b/test/unit/util/tor_tools.py
index 5035d7b4..285b4dde 100644
--- a/test/unit/util/tor_tools.py
+++ b/test/unit/util/tor_tools.py
@@ -3,12 +3,67 @@ Unit tests for the stem.util.tor_tools functions.
 """
 
 import unittest
+import os
 
 import stem.util.str_tools
 import stem.util.tor_tools
 
 
 class TestTorTools(unittest.TestCase):
+
+  def test_is_valid_hidden_service_address(self):
+"""
+Check hidden service addresses are valid (no .onion)
+"""
+valid_v2_addresses = [
+  'facebookcorewwwi',
+  '',
+]
+invalid_v2_addresses = [
+  'facebookcorewww',
+  'facebookcorewwyi'
+  'facebookc0rewwwi',
+  'facebookcorew wi',
+  None,
+  0,
+  1,
+  -1,
+  os.urandom(8)
+]
+
+for address in valid_v2_addresses:
+  
self.assertTrue(stem.util.tor_tools.is_valid_hidden_service_address(address))
+  
self.assertTrue(stem.util.tor_tools.is_valid_hidden_service_address(address, 
version=2))
+
+for address in invalid_v2_addresses:
+  
self.assertFalse(stem.util.tor_tools.is_valid_hidden_service_address(address))
+  
self.assertFalse(stem.util.tor_tools.is_valid_hidden_service_address(address, 
version=2))
+
+# Test version 3 addresses
+valid_v3_addresses = [
+  'pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd',
+  'sp3k262uwy4r2k3ycr5awluarykdpag6a7y33jxop4cs2lu5uz5sseqd',
+  'xa4r2iadxm55fbnqgwwi5mymqdcofiu3w6rpbtqn7b2dyn7mgwj64jyd'
+  ]
+invalid_v3_addresses = [
+  'pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryc', # bad version
+  'xa4r2iadxm55fbnqgwwi5mymqdcofiu3w6rpbtqn7b2dyn7mgwj64jy', # too short
+  'sp3k262uwy4r2k4ycr5awluarykdpag6a7y33jxop4cs2lu5uz5sseqd', # checksum 
mismatch
+  'pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscrybd', # too long
+  None,
+  0,
+  1,
+  -1,
+  os.urandom(56)
+]
+
+for address in valid_v3_addresses:
+  
self.assertTrue(stem.util.tor_tools.is_valid_hidden_service_address(address))
+  
self.assertTrue(stem.util.tor_tools.is_valid_hidden_service_address(address, 
version=3))
+for address in invalid_v3_addresses:
+  
self.assertFalse(stem.util.tor_tools.is_valid_hidden_service_address(address))
+  
self.assertFalse(stem.util.tor_tools.is_valid_hidden_service_address(address, 
version=3))
+
   def test_is_valid_fingerprint(self):
 """
 Checks the is_valid_fingerprint function.



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Fix test_version_argument to work with recent Tors.

2021-01-11 Thread atagar
commit 625a902533b9c3429b09fc2f01800b35dfc4179c
Author: Nick Mathewson 
Date:   Tue Dec 8 08:15:36 2020 -0500

Fix test_version_argument to work with recent Tors.

Tor now reports versions of libraries and the compilers use to build
it.  Only the first line has the Tor version.
---
 test/integ/process.py | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/test/integ/process.py b/test/integ/process.py
index 6abd9e6a..c2388146 100644
--- a/test/integ/process.py
+++ b/test/integ/process.py
@@ -107,7 +107,11 @@ class TestProcess(unittest.TestCase):
 Check that 'tor --version' matches 'GETINFO version'.
 """
 
-assert_equal('Tor version %s.\n' % test.tor_version(), run_tor(tor_cmd, 
'--version'))
+# We're only interested in the first line of output:
+# Other lines are about libraries and compilers.
+tor_version = run_tor(tor_cmd,  '--version').split("\n")[0]
+
+assert_equal('Tor version %s.' % test.tor_version(), tor_version)
 
   @asynchronous
   def test_help_argument(tor_cmd):

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Make Query.start() synchronous

2020-11-07 Thread atagar
commit 09dcc95f2c4e50477e1b0938cc83e58677e2288e
Author: Damian Johnson 
Date:   Sat Oct 31 14:32:04 2020 -0700

Make Query.start() synchronous

This class method initializes an asynchronous process. There's no benefit in
this method itself being asynchronous. This only was to ensure there's a 
loop
available, but our Synchronous parent provides that.
---
 stem/descriptor/remote.py | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/stem/descriptor/remote.py b/stem/descriptor/remote.py
index 2e9ec641..e8367e8b 100644
--- a/stem/descriptor/remote.py
+++ b/stem/descriptor/remote.py
@@ -436,17 +436,14 @@ class Query(Synchronous):
 if block:
   self.run(True)
 
-  async def start(self) -> None:
+  def start(self) -> None:
 """
 Starts downloading the scriptors if we haven't started already.
 """
 
 with self._downloader_lock:
   if self._downloader_task is None:
-# TODO: replace with get_running_loop() when we remove python 3.6 
support
-
-loop = asyncio.get_event_loop()
-self._downloader_task = 
loop.create_task(self._download_descriptors(self.retries, self.timeout))
+self._downloader_task = 
self._loop.create_task(Query._download_descriptors(self, self.retries, 
self.timeout))
 
   async def run(self, suppress: bool = False) -> 
List['stem.descriptor.Descriptor']:
 """
@@ -473,7 +470,7 @@ class Query(Synchronous):
 
   async def _run(self, suppress: bool) -> 
AsyncIterator[stem.descriptor.Descriptor]:
 with self._downloader_lock:
-  await self.start()
+  self.start()
   await self._downloader_task
 
   if self.error:



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Remove Query's Synchronous usage

2020-11-07 Thread atagar
commit 7ce8a5e090fc95bfb874299d61c824638d5242f4
Author: Damian Johnson 
Date:   Sat Nov 7 17:18:53 2020 -0800

Remove Query's Synchronous usage

First step to remove our asyncio metaprogramming...

  https://github.com/torproject/stem/issues/77

Our Query class now provides a run method for synchronous users, and 
run_async
for asyncio. This also adds a stop method that can cancel our download.
---
 stem/descriptor/remote.py  | 114 -
 test/unit/descriptor/remote.py |  53 ++-
 2 files changed, 130 insertions(+), 37 deletions(-)

diff --git a/stem/descriptor/remote.py b/stem/descriptor/remote.py
index 136b9d15..50b3065c 100644
--- a/stem/descriptor/remote.py
+++ b/stem/descriptor/remote.py
@@ -100,8 +100,7 @@ import stem.util.tor_tools
 
 from stem.descriptor import Compression
 from stem.util import log, str_tools
-from stem.util.asyncio import Synchronous
-from typing import Any, AsyncIterator, Dict, List, Optional, Sequence, Tuple, 
Union
+from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, 
Sequence, Tuple, Union
 
 # Tor has a limited number of descriptors we can fetch explicitly by their
 # fingerprint or hashes due to a limit on the url length by squid proxies.
@@ -227,7 +226,7 @@ def get_detached_signatures(**query_args: Any) -> 
'stem.descriptor.remote.Query'
   return get_instance().get_detached_signatures(**query_args)
 
 
-class Query(Synchronous):
+class Query(object):
   """
   Asynchronous request for descriptor content from a directory authority or
   mirror. These can either be made through the
@@ -369,7 +368,6 @@ class Query(Synchronous):
 super(Query, self).__init__()
 
 if not resource.startswith('/'):
-  self.stop()
   raise ValueError("Resources should start with a '/': %s" % resource)
 
 if resource.endswith('.z'):
@@ -380,7 +378,6 @@ class Query(Synchronous):
 elif isinstance(compression, stem.descriptor._Compression):
   compression = [compression]  # caller provided only a single option
 else:
-  self.stop()
   raise ValueError('Compression should be a list of 
stem.descriptor.Compression, was %s (%s)' % (compression, 
type(compression).__name__))
 
 if Compression.ZSTD in compression and not Compression.ZSTD.available:
@@ -404,7 +401,6 @@ class Query(Synchronous):
 if isinstance(endpoint, (stem.ORPort, stem.DirPort)):
   self.endpoints.append(endpoint)
 else:
-  self.stop()
   raise ValueError("Endpoints must be an stem.ORPort or stem.DirPort. 
'%s' is a %s." % (endpoint, type(endpoint).__name__))
 
 self.resource = resource
@@ -428,6 +424,12 @@ class Query(Synchronous):
 self._downloader_task = None  # type: Optional[asyncio.Task]
 self._downloader_lock = threading.RLock()
 
+# background thread if outside an asyncio context
+
+self._loop = None  # type: Optional[asyncio.AbstractEventLoop]
+self._loop_thread = None  # type: Optional[threading.Thread]
+self._loop_lock = threading.RLock()
+
 if start:
   self.start()
 
@@ -441,9 +443,38 @@ class Query(Synchronous):
 
 with self._downloader_lock:
   if self._downloader_task is None:
-self._downloader_task = 
self._loop.create_task(Query._download_descriptors(self, self.retries, 
self.timeout))
+with self._loop_lock:
+  if self._loop is None:
+try:
+  self._loop = asyncio.get_running_loop()
+except RuntimeError:
+  self._loop = asyncio.new_event_loop()
+  self._loop_thread = threading.Thread(
+name = 'stem.descriptor.remote query',
+target = self._loop.run_forever,
+daemon = True,
+  )
+
+  self._loop_thread.start()
+
+self._downloader_task = 
self._loop.create_task(self._download_descriptors(self.retries, self.timeout))
+
+  def stop(self) -> None:
+"""
+Aborts our download if it's in progress, and cleans up underlying
+resources.
+"""
 
-  async def run(self, suppress: bool = False) -> 
List['stem.descriptor.Descriptor']:
+with self._downloader_lock:
+  if self._downloader_task and not self._downloader_task.done():
+self._downloader_task.cancel()
+
+with self._loop_lock:
+  if self._loop_thread and self._loop_thread.is_alive():
+self._loop.call_soon_threadsafe(self._loop.stop)
+self._loop_thread.join()
+
+  def run(self, suppress: bool = False) -> List['stem.descriptor.Descriptor']:
 """
 Blocks until our request is complete then provides the descriptors. If we
 haven't yet started our request then this does so.
@@ -461,12 +492,43 @@ class Query(Synchronous):
 * :class:`~stem.DownloadFailed` if our request fails
 """
 
-try:
-  return [desc async for desc in self._run(suppress)]
-finally:
-  self.stop()
+if not self.downloaded and not 

[tor-commits] [stem/master] Test re-run command broken with python 3.1+

2020-11-07 Thread atagar
commit 757a61454d1c3be2eb68a9afb481eae1a0ed6130
Author: Damian Johnson 
Date:   Fri Nov 6 15:17:11 2020 -0800

Test re-run command broken with python 3.1+

Python's unittest module added the first line of our docstrings to the test
output...

  
https://docs.python.org/3/library/unittest.html#unittest.TestCase.shortDescription

This broke our code that provides a command to re-run test failures. That 
is to
say, rather than presenting...

  TESTING FAILED (9 seconds)
[UNIT TEST] test_download 
(test.unit.descriptor.remote.TestDescriptorDownloader) ... FAIL

  You can re-run just these tests with:

./run_tests.py --unit --test descriptor.remote

... we lacked the last line.
---
 stem/util/test_tools.py | 8 
 1 file changed, 8 insertions(+)

diff --git a/stem/util/test_tools.py b/stem/util/test_tools.py
index 96aae590..7343e674 100644
--- a/stem/util/test_tools.py
+++ b/stem/util/test_tools.py
@@ -248,6 +248,14 @@ class TimedTestRunner(unittest.TextTestRunner):
 
   return self.assertRaisesRegexp(exc_type, '^%s$' % 
re.escape(exc_msg), *args, **kwargs)
 
+def shortDescription(self):
+  # Python now prints the first line of a test's docstring by default.
+  # This breaks our output parsers so disabling the feature...
+  #
+  #   
https://stackoverflow.com/questions/12962772/how-to-stop-python-unittest-from-printing-test-docstring
+
+  return None
+
 def id(self) -> str:
   return '%s.%s.%s' % (original_type.__module__, 
original_type.__name__, self._testMethodName)
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test that the Query class' 'start' argument works

2020-11-07 Thread atagar
commit bb0d68bee8477f3963dbbfef9a2713e30bed85e7
Author: Damian Johnson 
Date:   Sat Oct 31 14:22:27 2020 -0700

Test that the Query class' 'start' argument works

Reading our Query class I became worried that our 'start' argument fails to 
get
honored because the start() method is asynchronous (so its invocation 
returns a
coroutine rather than running it).

I was wrong. It works because as a Synchronous subclass our metaprogramming
converts the call. That said, this is none the less a good thing to check.
---
 test/unit/descriptor/remote.py | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/test/unit/descriptor/remote.py b/test/unit/descriptor/remote.py
index 7447fd16..58c7276a 100644
--- a/test/unit/descriptor/remote.py
+++ b/test/unit/descriptor/remote.py
@@ -78,6 +78,21 @@ class TestDescriptorDownloader(unittest.TestCase):
 # prevent our mocks from impacting other tests
 stem.descriptor.remote.SINGLETON_DOWNLOADER = None
 
+  @mock_download(TEST_DESCRIPTOR)
+  def test_initial_startup(self):
+"""
+Check that the query can begin downloading in the background when first
+constructed.
+"""
+
+query = 
stem.descriptor.remote.get_server_descriptors('9695DFC35FFEB861329B9F1AB04C46397020CE31',
 start = False)
+self.assertTrue(query._downloader_task is None)
+query.stop()
+
+query = 
stem.descriptor.remote.get_server_descriptors('9695DFC35FFEB861329B9F1AB04C46397020CE31',
 start = True)
+self.assertTrue(query._downloader_task is not None)
+query.stop()
+
   @mock_download(TEST_DESCRIPTOR)
   def test_download(self):
 """



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Cache parsed descriptors within Query

2020-11-07 Thread atagar
commit 6a7ebd9f12f89aa359d2df32cb47a44707a61008
Author: Damian Johnson 
Date:   Sun Nov 1 15:15:47 2020 -0800

Cache parsed descriptors within Query

Our Query class cached the bytes we download rather than parsed descriptors.
This could be advantagous if a user downloads descriptors without caring
about the results (unlikely), but otherwise it's all downside...

  * Slower: The Query class downloads asynchronously so we can parallelize.
By parsing when the results are requested we serialize that part of the
runtime.

  * Memory: Caching bytes reduced the upfront memory usage, but multiplies
it upon retrieving the results because we create fresh Descriptor
objects upon each invocation.

  * Duplication: Each invocation of our run method re-parsed the 
descriptors.
For larger documents like the consensus this duplicates a lot of work.

  * Complexity: Caching bytes needlessly complicated the run method.
---
 stem/descriptor/remote.py | 67 +++
 1 file changed, 27 insertions(+), 40 deletions(-)

diff --git a/stem/descriptor/remote.py b/stem/descriptor/remote.py
index e8367e8b..136b9d15 100644
--- a/stem/descriptor/remote.py
+++ b/stem/descriptor/remote.py
@@ -338,9 +338,8 @@ class Query(Synchronous):
   :var bool fall_back_to_authority: when retrying request issues the last
 request to a directory authority if **True**
 
-  :var str content: downloaded descriptor content
+  :var list downloaded: downloaded descriptors, **None** if not yet retrieved
   :var Exception error: exception if a problem occured
-  :var bool is_done: flag that indicates if our request has finished
 
   :var float start_time: unix timestamp when we first started running
   :var dict reply_headers: headers provided in the response,
@@ -413,9 +412,8 @@ class Query(Synchronous):
 self.retries = retries
 self.fall_back_to_authority = fall_back_to_authority
 
-self.content = None  # type: Optional[bytes]
+self.downloaded = None  # type: Optional[List[stem.descriptor.Descriptor]]
 self.error = None  # type: Optional[BaseException]
-self.is_done = False
 self.download_url = None  # type: Optional[str]
 
 self.start_time = None  # type: Optional[float]
@@ -470,8 +468,14 @@ class Query(Synchronous):
 
   async def _run(self, suppress: bool) -> 
AsyncIterator[stem.descriptor.Descriptor]:
 with self._downloader_lock:
-  self.start()
-  await self._downloader_task
+  if not self.downloaded and not self.error:
+if not self._downloader_task:
+  self.start()
+
+try:
+  self.downloaded = await self._downloader_task
+except Exception as exc:
+  self.error = exc
 
   if self.error:
 if suppress:
@@ -479,30 +483,8 @@ class Query(Synchronous):
 
 raise self.error
   else:
-if self.content is None:
-  if suppress:
-return
-
-  raise ValueError('BUG: _download_descriptors() finished without 
either results or an error')
-
-try:
-  results = stem.descriptor.parse_file(
-io.BytesIO(self.content),
-self.descriptor_type,
-validate = self.validate,
-document_handler = self.document_handler,
-**self.kwargs
-  )
-
-  for desc in results:
-yield desc
-except ValueError as exc:
-  self.error = exc  # encountered a parsing error
-
-  if suppress:
-return
-
-  raise self.error
+for desc in self.downloaded:
+  yield desc
 
   async def __aiter__(self) -> AsyncIterator[stem.descriptor.Descriptor]:
 async for desc in self._run(True):
@@ -526,7 +508,7 @@ class Query(Synchronous):
 else:
   return random.choice(self.endpoints)
 
-  async def _download_descriptors(self, retries: int, timeout: 
Optional[float]) -> None:
+  async def _download_descriptors(self, retries: int, timeout: 
Optional[float]) -> List['stem.descriptor.Descriptor']:
 self.start_time = time.time()
 
 retries = self.retries
@@ -545,17 +527,24 @@ class Query(Synchronous):
 
   try:
 response = await asyncio.wait_for(self._download_from(endpoint), 
time_remaining)
-self.content, self.reply_headers = _http_body_and_headers(response)
+content, self.reply_headers = _http_body_and_headers(response)
 
-self.is_done = True
 self.runtime = time.time() - self.start_time
 
 log.trace('Descriptors retrieved from %s in %0.2fs' % 
(downloaded_from, self.runtime))
-return
+
+try:
+  return list(stem.descriptor.parse_file(
+io.BytesIO(content),
+self.descriptor_type,
+validate = self.validate,
+document_handler = self.document_handler,
+**self.kwargs
+  ))
+except ValueError:
+  raise  # 

[tor-commits] [stem/master] Drop test_tools skip function

2020-10-29 Thread atagar
commit 69792368ed6a45c1877360872b751e6077031065
Author: Damian Johnson 
Date:   Thu Oct 29 17:39:55 2020 -0700

Drop test_tools skip function

When we dropped python 2.x support this function became moot.
---
 stem/util/test_tools.py | 16 
 test/integ/process.py   |  6 +++---
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/stem/util/test_tools.py b/stem/util/test_tools.py
index ac9f8b88..96aae590 100644
--- a/stem/util/test_tools.py
+++ b/stem/util/test_tools.py
@@ -96,22 +96,6 @@ def assert_in(expected: Any, actual: Any, msg: Optional[str] 
= None) -> None:
 raise AssertionError("Expected '%s' to be within '%s'" % (expected, 
actual) if msg is None else msg)
 
 
-def skip(msg: str) -> None:
-  """
-  Function form of a TestCase's skipTest.
-
-  .. versionadded:: 1.6.0
-
-  :param msg: reason test is being skipped
-
-  :raises: **unittest.case.SkipTest** for this reason
-  """
-
-  # TODO: remove now that python 2.x is unsupported?
-
-  raise unittest.case.SkipTest(msg)
-
-
 def asynchronous(func: Callable) -> Callable:
   test = stem.util.test_tools.AsyncTest(func)
   ASYNC_TESTS[test.name] = test
diff --git a/test/integ/process.py b/test/integ/process.py
index d5c7f2f0..6abd9e6a 100644
--- a/test/integ/process.py
+++ b/test/integ/process.py
@@ -26,7 +26,7 @@ import test.require
 from contextlib import contextmanager
 from unittest.mock import patch, Mock
 
-from stem.util.test_tools import async_test, asynchronous, assert_equal, 
assert_in, skip
+from stem.util.test_tools import async_test, asynchronous, assert_equal, 
assert_in
 
 BASIC_RELAY_TORRC = """\
 SocksPort 9089
@@ -255,7 +255,7 @@ class TestProcess(unittest.TestCase):
 """
 
 if not stem.util.system.is_available('sleep'):
-  skip('(sleep unavailable)')
+  raise unittest.case.SkipTest('(sleep unavailable)')
 
 with patch('re.compile', Mock(side_effect = KeyboardInterrupt('nope'))):
   # We don't need to actually run tor for this test. Rather, any process 
will
@@ -547,7 +547,7 @@ class TestProcess(unittest.TestCase):
 """
 
 if not stem.util.system.is_available('sleep'):
-  skip('(sleep unavailable)')
+  raise unittest.case.SkipTest('(sleep unavailable)')
 
 with tempfile.TemporaryDirectory() as data_directory:
   sleep_process = subprocess.Popen(['sleep', '60'])

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] Replace references to a nyxrc

2020-10-28 Thread atagar
settings
 def _warn_about_unused_config_keys(config):
   """
-  Provides a notice if the user's nyxrc has any entries that are unused.
+  Provides a notice if the user's nyx configuration has any entries that are 
unused.
   """
 
   for key in sorted(config.unused_keys()):
diff --git a/test/panel/log.py b/test/panel/log.py
index a05ed4f..bb27ef7 100644
--- a/test/panel/log.py
+++ b/test/panel/log.py
@@ -25,9 +25,9 @@ EXPECTED_WRAPPED_MSG = """\
 
 EXPECTED_ENTRIES = """\
  16:41:37 [NYX_WARNING] Tor's geoip database is unavailable.
- 16:41:37 [NYX_NOTICE] No nyxrc loaded, using defaults. You can customize nyx 
by
-   placing a configuration file at /home/atagar/.nyx/nyxrc (see the 
nyxrc.sample
-   for its options).
+ 16:41:37 [NYX_NOTICE] No nyx configuration loaded, using defaults. You can
+   customize nyx by placing a configuration file at /home/atagar/.nyx/config
+   (see https://nyx.torproject.org/nyxrc.sample for its options).
  16:41:37 [NOTICE] New control connection opened from 127.0.0.1.
  16:41:37 [NOTICE] Opening OR listener on 0.0.0.0:7000
  16:41:37 [NOTICE] Opening Control listener on 127.0.0.1:9051
@@ -41,9 +41,9 @@ EXPECTED_ENTRIES = """\
 EXPECTED_ENTRIES_WITH_BORDER = """\
 +-October 26, 
2011-+
 |16:41:37 [NYX_WARNING] Tor's geoip database is unavailable.   
|
-|16:41:37 [NYX_NOTICE] No nyxrc loaded, using defaults. You can customize nyx  
|
-|  by placing a configuration file at /home/atagar/.nyx/nyxrc (see the 
|
-|  nyxrc.sample for its options).  
|
+|16:41:37 [NYX_NOTICE] No nyx configuration loaded, using defaults. You can
|
+|  customize nyx by placing a configuration file at /home/atagar/.nyx/config   
|
+|  (see https://nyx.torproject.org/nyxrc.sample for its options).  
|
 |16:41:37 [NOTICE] New control connection opened from 127.0.0.1.   
|
 |16:41:37 [NOTICE] Opening OR listener on 0.0.0.0:7000 
|
 |16:41:37 [NOTICE] Opening Control listener on 127.0.0.1:9051  
|
@@ -62,7 +62,7 @@ TIME_STRUCT = time.gmtime(NOW)
 def entries():
   return [
 LogEntry(NOW, 'NYX_WARNING', "Tor's geoip database is unavailable."),
-LogEntry(NOW, 'NYX_NOTICE', 'No nyxrc loaded, using defaults. You can 
customize nyx by placing a configuration file at /home/atagar/.nyx/nyxrc (see 
the nyxrc.sample for its options).'),
+LogEntry(NOW, 'NYX_NOTICE', 'No nyx configuration loaded, using defaults. 
You can customize nyx by placing a configuration file at 
/home/atagar/.nyx/config (see https://nyx.torproject.org/nyxrc.sample for its 
options).'),
 LogEntry(NOW, 'NOTICE', 'New control connection opened from 127.0.0.1.'),
 LogEntry(NOW, 'NOTICE', 'Opening OR listener on 0.0.0.0:7000'),
 LogEntry(NOW, 'NOTICE', 'Opening Control listener on 127.0.0.1:9051'),
diff --git a/web/index.html b/web/index.html
index adfadb5..7ef511b 100644
--- a/web/index.html
+++ b/web/index.html
@@ -275,7 +275,7 @@ E: Unable to locate package nyx
   Is bandwidth graphed in bits or bytes?
   
 Bytes. Most tools measure in bytes so for consistency we 
do the same. Unfortunately hosting providers advertise in bits to inflate their 
numbers ("5 Mbit connection"). If graphs show just one eighth of what you 
expect this is why.
-To graph in bits rather than bytes add the following to your nyxrc...
+To graph in bits rather than bytes add the following to your nyx configuration...
 show_bits true
   
 
@@ -285,7 +285,7 @@ E: Unable to locate package nyx
   
 
 When alternate character support (ACS) http://invisible-island.net/ncurses/ncurses.faq.html#no_line_drawing;>is 
unavailable borders become characters like the picture above. This is a 
terminal bug.
-Unfortunately there doesn't seem to be a way for Nyx to 
automatically detect this. However, when it happens this can be easily 
corrected. Simply run reset. To tell Nyx not to use ACS borders simply 
add the following to your nyxrc...
+Unfortunately there doesn't seem to be a way for Nyx to 
automatically detect this. However, when it happens this can be easily 
corrected. Simply run reset. To tell Nyx not to use ACS borders simply 
add the following to your nyx configuration...
 acs_support false
   
 
@@ -487,18 +487,18 @@ sudo python setup.py install
   
   Configuration
 
-  Like many terminal applications Nyx can be customized through a 
configuration file. By default ~/.nyx/nyxrc, though you can specify one 
with nyx --config /path/to/nyxrc.
+  Like many terminal applications Nyx can be customized through a 
configuration file. By default ~/.nyx/co

[tor-commits] [stem/master] Permit float in label functions

2020-10-28 Thread atagar
commit 84602486f5a6eb2c4558656ca4f532e4bc81e92b
Author: Damian Johnson 
Date:   Wed Oct 28 16:40:36 2020 -0700

Permit float in label functions

Oops. Actually, our last release allowed floats (and our 'decimal' argument
doesn't make terribly much sense otherwise). We *did* have a bug in that
remainder values that are less than 1 crashed us (corrected by commit 
c90e87c),
but we shouldn't have addressed that by integer normalization.

Regression caught thanks to Nyx's tests...

  ==
  FAIL: test_draw_line (panel.connection.TestConnectionPanel)
  --
  Traceback (most recent call last):
File "/home/atagar/Desktop/nyx/test/__init__.py", line 59, in wrapped
  return func(self, *args, **kwargs)
File "/usr/lib/python3.8/unittest/mock.py", line 1325, in patched
  return func(*newargs, **newkeywargs)
    File "/home/atagar/Desktop/nyx/test/panel/connection.py", line 228, in 
test_draw_line
  self.assertEqual(expected, rendered.content)
  AssertionError: ' 75.119.206.243:22 (de)  -->  82.121.9.9:3531
  15.4s (INBOUND)' != ' 75.119.206.243:22 (de)  -->  82.121.9.9:3531
  14.9s (INBOUND)'
  -  75.119.206.243:22 (de)  -->  82.121.9.9:3531  15.4s 
(INBOUND)
  ? ^ ^
  +  75.119.206.243:22 (de)  -->  82.121.9.9:3531  14.9s 
(INBOUND)
  ? ^ ^
---
 docs/change_log.rst |  1 +
 stem/util/str_tools.py  | 24 ++--
 test/unit/util/str_tools.py |  1 +
 3 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/docs/change_log.rst b/docs/change_log.rst
index cc830d6c..b3544569 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -65,6 +65,7 @@ The following are only available within Stem's `git repository
 
  * **Descriptors**
 
+  * Cached CollecTor files always reported a hash mismatch (:ticket:`76`)
   * *transport* lines within extrainfo descriptors failed to validate
 
  * **Utilities**
diff --git a/stem/util/str_tools.py b/stem/util/str_tools.py
index 9803d437..a9a34364 100644
--- a/stem/util/str_tools.py
+++ b/stem/util/str_tools.py
@@ -298,7 +298,7 @@ def crop(msg: str, size: int, min_word_length: int = 4, 
min_crop: int = 0, endin
   return (return_msg, remainder) if get_remainder else return_msg
 
 
-def size_label(byte_count: int, decimal: int = 0, is_long: bool = False, 
is_bytes: bool = True, round: bool = False) -> str:
+def size_label(byte_count: Union[int, float], decimal: int = 0, is_long: bool 
= False, is_bytes: bool = True, round: bool = False) -> str:
   """
   Converts a number of bytes into a human readable label in its most
   significant units. For instance, 7500 bytes would return "7 KB". If the
@@ -329,16 +329,13 @@ def size_label(byte_count: int, decimal: int = 0, 
is_long: bool = False, is_byte
   :returns: **str** with human readable representation of the size
   """
 
-  if isinstance(byte_count, float):
-byte_count = int(byte_count)
-
   if is_bytes:
 return _get_label(SIZE_UNITS_BYTES, byte_count, decimal, is_long, round)
   else:
 return _get_label(SIZE_UNITS_BITS, byte_count, decimal, is_long, round)
 
 
-def time_label(seconds: int, decimal: int = 0, is_long: bool = False) -> str:
+def time_label(seconds: Union[int, float], decimal: int = 0, is_long: bool = 
False) -> str:
   """
   Converts seconds into a time label truncated to its most significant units.
   For instance, 7500 seconds would return "2h". Units go up through days.
@@ -366,13 +363,10 @@ def time_label(seconds: int, decimal: int = 0, is_long: 
bool = False) -> str:
   :returns: **str** with human readable representation of the time
   """
 
-  if isinstance(seconds, float):
-seconds = int(seconds)
-
   return _get_label(TIME_UNITS, seconds, decimal, is_long)
 
 
-def time_labels(seconds: int, is_long: bool = False) -> Sequence[str]:
+def time_labels(seconds: Union[int, float], is_long: bool = False) -> 
Sequence[str]:
   """
   Provides a list of label conversions for each time unit, starting with its
   most significant units on down. Any counts that evaluate to zero are omitted.
@@ -392,9 +386,6 @@ def time_labels(seconds: int, is_long: bool = False) -> 
Sequence[str]:
   :returns: **list** of strings with human readable representations of the time
   """
 
-  if isinstance(seconds, float):
-seconds = int(seconds)
-
   time_labels = []
 
   for count_per_unit, _, _ in TIME_UNITS:
@@ -405,7 +396,7 @@ def time_labels(seconds: int, is_long: bool = Fal

[tor-commits] [nyx/master] Fix unit tests

2020-10-28 Thread atagar
commit 3ea784a3af26e6772e8ab3531e7185895567a6c7
Author: Damian Johnson 
Date:   Wed Oct 28 15:02:01 2020 -0700

Fix unit tests

I don't run Nyx's unit tests very often so a few regressions slipped in. 
Some
due to Nyx adjustments, some from Stem.

Stem renamed its is_pep8_available() function to
is_pycodestyle_available() because the upstream project renamed itself...

  Traceback (most recent call last):
File "./run_tests.py", line 80, in 
  main()
File "/home/atagar/Desktop/nyx/stem/util/conf.py", line 289, in wrapped
  return func(*args, **kwargs)
File "./run_tests.py", line 46, in main
  if stem.util.test_tools.is_pep8_available():
  AttributeError: module 'stem.util.test_tools' has no attribute 
'is_pep8_available'
---
 nyx/__init__.py  |  1 +
 nyx/curses.py|  2 +-
 nyx/panel/log.py |  2 +-
 run_tests.py |  2 +-
 setup.py |  2 +-
 test/panel/config.py |  2 +-
 test/panel/connection.py | 12 
 test/panel/header.py |  2 +-
 8 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/nyx/__init__.py b/nyx/__init__.py
index 67053aa..9fbf2c0 100644
--- a/nyx/__init__.py
+++ b/nyx/__init__.py
@@ -138,6 +138,7 @@ def conf_handler(key, value):
   if key == 'redraw_rate':
 return max(1, value)
 
+
 CONFIG = stem.util.conf.config_dict('nyx', {
   'confirm_quit': True,
   'redraw_rate': 5,
diff --git a/nyx/curses.py b/nyx/curses.py
index 3c3fa69..5ff5cfb 100644
--- a/nyx/curses.py
+++ b/nyx/curses.py
@@ -115,7 +115,7 @@ RED, GREEN, YELLOW, BLUE, CYAN, MAGENTA, BLACK, WHITE = 
list(Color)
 
 Attr = stem.util.enum.Enum('NORMAL', 'BOLD', 'UNDERLINE', 'HIGHLIGHT')
 NORMAL, BOLD, UNDERLINE, HIGHLIGHT = list(Attr)
-ANSI_RE = re.compile('\x1B\[([0-9;]+)m')
+ANSI_RE = re.compile('\x1B\\[([0-9;]+)m')
 
 CURSES_COLORS = {
   Color.RED: curses.COLOR_RED,
diff --git a/nyx/panel/log.py b/nyx/panel/log.py
index bbb1961..c6587a1 100644
--- a/nyx/panel/log.py
+++ b/nyx/panel/log.py
@@ -196,7 +196,7 @@ class LogPanel(nyx.panel.DaemonPanel):
 try:
   if not os.path.exists(base_dir):
 os.makedirs(base_dir)
-except OSError as exc:
+except OSError:
   raise IOError("unable to make directory '%s'" % base_dir)
 
 event_log = list(self._event_log)
diff --git a/run_tests.py b/run_tests.py
index 4c7f73d..3cab8a6 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -43,7 +43,7 @@ def main():
   if stem.util.test_tools.is_pyflakes_available():
 pyflakes_task = 
stem.util.system.DaemonTask(stem.util.test_tools.pyflakes_issues, (SRC_PATHS,), 
start = True)
 
-  if stem.util.test_tools.is_pep8_available():
+  if stem.util.test_tools.is_pycodestyle_available():
 pycodestyle_task = 
stem.util.system.DaemonTask(stem.util.test_tools.stylistic_issues, 
(SRC_PATHS,), start = True)
 
   tests = unittest.defaultTestLoader.discover('test', pattern = '*.py')
diff --git a/setup.py b/setup.py
index 7e9b996..a4cd132 100644
--- a/setup.py
+++ b/setup.py
@@ -51,7 +51,7 @@ global-exclude *~
 # installation. As such, just reading our file for the parameters we need.
 
 ATTR = {}
-ATTR_LINE = re.compile("^__(\S+)__ = '(.+)'")
+ATTR_LINE = re.compile("^__(\\S+)__ = '(.+)'")
 
 with open('nyx/__init__.py') as init_file:
   for line in init_file:
diff --git a/test/panel/config.py b/test/panel/config.py
index 0bf51ab..7b138d0 100644
--- a/test/panel/config.py
+++ b/test/panel/config.py
@@ -20,7 +20,7 @@ EXPECTED_LINE = 'ControlPort   9051   Port 
providing access to t
 EXPECTED_DETAIL_DIALOG = """
 
+--+
 | ControlPort (General Option) 
|
-| Value: 9051 (custom, LineList, usage: PORT|unix:path|auto [flags])   
|
+| Value: 9051 (custom, LineList, usage: [address:]port|unix:path|auto [flags]) 
|
 | Description: If set, Tor will accept connections on this port and allow 
those|
 |   connections to control the Tor process using the Tor Control Protocol 
(des-|
 |   cribed in control-spec.txt in torspec). Note: unless you also specify one  
|
diff --git a/test/panel/connection.py b/test/panel/connection.py
index b432df5..56a7a66 100644
--- a/test/panel/connection.py
+++ b/test/panel/connection.py
@@ -201,8 +201,10 @@ class TestConnectionPanel(unittest.TestCase):
   @require_curses
   @patch('nyx.panel.connection.tor_controller')
   def test_draw_line(self, tor_controller_mock):
-tor_controller_mock().is_geoip_unavailable.return_value = False
-tor_controller_mock().get_info.return_value = '82.121.9.9'
+tor_controller_mock().get_info.side_effect = lambda param, default = None: 
{
+  'ip-to-country/ipv4-available': '1',
+  'address': '82.121.9.9',
+}[param]
 
 test_data = ((
   line(),
@@ -228,8 +230,10 @@

[tor-commits] [nyx/master] Config options mistakenly reported as unused

2020-10-27 Thread atagar
commit 67fb8ef429b52a5c878a79484ae5b1b316643476
Author: Damian Johnson 
Date:   Tue Oct 27 17:31:26 2020 -0700

Config options mistakenly reported as unused

Oops, these config options were used after the 'warn if unused' check...

  https://github.com/torproject/nyx/issues/32
---
 nyx/starter.py | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/nyx/starter.py b/nyx/starter.py
index 4b0d279..be904fd 100644
--- a/nyx/starter.py
+++ b/nyx/starter.py
@@ -109,11 +109,13 @@ def main(config):
 
 stem.util.log.trace(TORRC.format(torrc_path = torrc_path, torrc_content = 
torrc_content))
 
+  use_acs = config.get('acs_support', True)
+
   _warn_if_root(controller)
   _warn_if_unable_to_get_pid(controller)
-  _warn_about_unused_config_keys()
   _use_unicode()
   _set_process_name()
+  _warn_about_unused_config_keys()
 
   # These os.putenv calls fail on FreeBSD, and even attempting causes python to
   # print the following to stdout...
@@ -125,7 +127,7 @@ def main(config):
 os.putenv('ESCDELAY', '0')  # make 'esc' take effect right away
 
   try:
-nyx.curses.start(nyx.draw_loop, acs_support = config.get('acs_support', 
True), transparent_background = True, cursor = False)
+nyx.curses.start(nyx.draw_loop, acs_support = use_acs, 
transparent_background = True, cursor = False)
   except KeyboardInterrupt:
 pass  # skip printing a stack trace
   finally:

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] Whitespace breaks logged_events

2020-10-27 Thread atagar
commit 1d5ecdf2d7aaf16a49b5e9ff3ebb2d35faac5c87
Author: Damian Johnson 
Date:   Tue Oct 27 17:14:04 2020 -0700

Whitespace breaks logged_events

When our logged_events has whitespace within it Nyx confusingly claims that 
the
events are not recognized. Caught thanks to Sai...

  https://github.com/torproject/nyx/issues/31
---
 nyx/panel/log.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nyx/panel/log.py b/nyx/panel/log.py
index 030be38..bbb1961 100644
--- a/nyx/panel/log.py
+++ b/nyx/panel/log.py
@@ -85,7 +85,7 @@ class LogPanel(nyx.panel.DaemonPanel):
   def __init__(self):
 nyx.panel.DaemonPanel.__init__(self, UPDATE_RATE)
 
-logged_events = CONFIG['logged_events'].split(',')
+logged_events = list(map(str.strip, CONFIG['logged_events'].split(',')))
 
 for alias, actual_event in EVENT_ALIASES.items():
   if alias in logged_events:

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] color_override config broken if different case

2020-10-26 Thread atagar
commit ed031ca750be06e4134d58b81448e60020c0cfd8
Author: Damian Johnson 
Date:   Mon Oct 26 18:06:18 2020 -0700

color_override config broken if different case

Oops, our code that validates color values normalizes into camel case, but
doesn't persist that normalization for its usage. As a result Nyx gets into 
a
pretty broken state. Caught thanks to Sai.

  https://github.com/torproject/nyx/issues/30
---
 nyx/curses.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/nyx/curses.py b/nyx/curses.py
index 98b1d11..3c3fa69 100644
--- a/nyx/curses.py
+++ b/nyx/curses.py
@@ -173,6 +173,8 @@ def conf_handler(key, value):
 
 if value not in Color and value != 'None':
   raise ValueError('"%s" isn\'t a valid color' % value)
+
+return value
   elif key == 'max_line_wrap':
 return max(1, value)
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] AttributeError when using --debug argument

2020-10-25 Thread atagar
commit 6cd89c4e13239f170c07c559a2653b7e25e47744
Author: Damian Johnson 
Date:   Sun Oct 25 18:59:26 2020 -0700

AttributeError when using --debug argument

Python 3.8 removed platform.dist(), causing us to error with...

  Traceback (most recent call last):
File "./run_nyx", line 14, in 
  nyx.main()
File "/home/atagar/Desktop/nyx/nyx/__init__.py", line 199, in main
  nyx.starter.main()
    File "/home/atagar/Desktop/nyx/stem/util/conf.py", line 287, in wrapped
  return func(*args, config = config, **kwargs)
File "/home/atagar/Desktop/nyx/nyx/starter.py", line 68, in main
  _setup_debug_logging(args)
File "/home/atagar/Desktop/nyx/nyx/starter.py", line 174, in 
_setup_debug_logging
  platform = ' '.join(platform.dist()),
  AttributeError: module 'platform' has no attribute 'dist'

Python doesn't have a builtin replacement, instead advising that users 
install
the distro package...

  https://pypi.org/project/distro/

This information isn't worth a new dependency so simply dropping it from our
debug output.
---
 nyx/starter.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/nyx/starter.py b/nyx/starter.py
index 75f0f64..4b0d279 100644
--- a/nyx/starter.py
+++ b/nyx/starter.py
@@ -30,7 +30,7 @@ DEBUG_HEADER = """
 Nyx {nyx_version} Debug Dump
 Stem Version: {stem_version}
 Python Version: {python_version}
-Platform: {system} ({platform})
+Platform: {system}
 

 Nyx Configuration ({nyxrc_path}):
 {nyxrc_content}
@@ -168,7 +168,6 @@ def _setup_debug_logging(args):
 stem_version = stem.__version__,
 python_version = '.'.join(map(str, sys.version_info[:3])),
 system = platform.system(),
-platform = ' '.join(platform.dist()),
 nyxrc_path = args.config,
 nyxrc_content = nyxrc_content,
   ))

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] Show FAQ when javascript is disabled

2020-10-24 Thread atagar
commit 3a53a21190b7a8a86a0e6e94b1be4fdccb6e7654
Author: Damian Johnson 
Date:   Sat Oct 24 17:05:52 2020 -0700

Show FAQ when javascript is disabled

Minor adjustment of a patch from Sai...

  https://github.com/torproject/nyx/issues/21
---
 web/index.html   | 20 +++-
 web/styles.css   |  2 --
 web/styles_no_js.css | 12 
 3 files changed, 3 insertions(+), 31 deletions(-)

diff --git a/web/index.html b/web/index.html
index f214a36..adfadb5 100644
--- a/web/index.html
+++ b/web/index.html
@@ -6,7 +6,6 @@
 Nyx
 
 
-
 
 
 
@@ -860,6 +859,7 @@ logged_events BW, NOTICE, WARN, ERR
 
 

[tor-commits] [stem/master] Error when reading CollecTor file twice

2020-10-24 Thread atagar
commit 78ad7080d6172365ddfbd50742ea42fa814c0485
Author: Damian Johnson 
Date:   Sat Oct 24 14:27:23 2020 -0700

Error when reading CollecTor file twice

When a CollecTor file is already within our cache we validate its hash 
against
CollecTor's index. However, files we wrote to disk are decompressed by 
default
so the hash naturally mismatches.

  https://github.com/torproject/stem/issues/76

Reproduced this issue with the following script...

  import stem.descriptor.collector

  collector = stem.descriptor.collector.get_instance()
  desc_file = collector.files(descriptor_type = 'server-descriptor')[0]  # 
pick any arbitrary file

  print('Number of descriptors (first read): %s' % 
len(list(desc_file.read(directory = '/tmp/collector_cache'
  print('Number of descriptors (second read): %s' % 
len(list(desc_file.read(directory = '/tmp/collector_cache'

Before...

  % python demo.py
  Number of descriptors (first read): 3112
  Traceback (most recent call last):
File "scrap.py", line 8, in 
  print('Number of descriptors (second read): %s' % 
len(list(desc_file.read(directory = '/tmp/collector_cache'
File "/home/atagar/Desktop/stem/stem/descriptor/collector.py", line 
273, in read
  path = self.download(directory, True, timeout, retries)
    File "/home/atagar/Desktop/stem/stem/descriptor/collector.py", line 
335, in download
  raise OSError("%s already exists but mismatches CollecTor's checksum 
(expected: %s, actual: %s)" % (path, expected_hash, actual_hash))
  OSError: /tmp/collector_cache/server-descriptors-2005-12.tar already 
exists but mismatches CollecTor's checksum (expected: 
bf700d8b6143e310219b2ce2810abd82f94bc295c7f08e9f1a88989562e33b2f, actual: 
32a5ea8fd761e5967fbb8d399742f0da7cbb1c79c1539f2e58cad2e668462652)

After...

  % python demo.py
  Number of descriptors (first read): 3112
  Number of descriptors (second read): 3112

We can either solve this by dropping the hash check or caching compressed
archives. Initially I leaned toward the former to expedite cache reads, but 
on
reflection the later is conceptually simpler. Essentially, is this a network
cache or a read cache? A network cache is safer in that if CollecTor 
replaces a
file (but keeps the same filename) this will catch the change.
---
 stem/descriptor/collector.py | 13 ++---
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/stem/descriptor/collector.py b/stem/descriptor/collector.py
index 892ccc30..a84d9724 100644
--- a/stem/descriptor/collector.py
+++ b/stem/descriptor/collector.py
@@ -270,7 +270,7 @@ class File(object):
 
 return
 
-path = self.download(directory, True, timeout, retries)
+path = self.download(directory, timeout, retries)
 
 # Archives can contain multiple descriptor types, so parsing everything and
 # filtering to what we're after.
@@ -290,13 +290,12 @@ class File(object):
 
 yield desc
 
-  def download(self, directory: str, decompress: bool = True, timeout: 
Optional[int] = None, retries: Optional[int] = 3, overwrite: bool = False) -> 
str:
+  def download(self, directory: str, timeout: Optional[int] = None, retries: 
Optional[int] = 3, overwrite: bool = False) -> str:
 """
 Downloads this file to the given location. If a file already exists this is
 a no-op.
 
 :param directory: destination to download into
-:param decompress: decompress written file
 :param timeout: timeout when connection becomes idle, no timeout
   applied if **None**
 :param retries: maximum attempts to impose
@@ -311,12 +310,7 @@ class File(object):
 """
 
 filename = self.path.split('/')[-1]
-
-if self.compression != Compression.PLAINTEXT and decompress:
-  filename = filename.rsplit('.', 1)[0]
-
 directory = os.path.expanduser(directory)
-
 path = os.path.join(directory, filename)
 
 if not os.path.exists(directory):
@@ -336,9 +330,6 @@ class File(object):
 
 response = stem.util.connection.download(COLLECTOR_URL + self.path, 
timeout, retries)
 
-if decompress:
-  response = self.compression.decompress(response)
-
 with open(path, 'wb') as output_file:
   output_file.write(response)
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Update website build instructions

2020-10-23 Thread atagar
commit cc7b22c8f7e28db52fde2b78286e3838843c4a3b
Author: Damian Johnson 
Date:   Fri Oct 23 18:10:38 2020 -0700

Update website build instructions

Building now requires the typehint plugin. Noting that and the pip command 
to
install it and sphinx.
---
 docs/faq.rst | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/docs/faq.rst b/docs/faq.rst
index 7df2dd51..765d864b 100644
--- a/docs/faq.rst
+++ b/docs/faq.rst
@@ -6,6 +6,7 @@ Frequently Asked Questions
  * :ref:`what_is_stem`
  * :ref:`does_stem_have_any_dependencies`
  * :ref:`what_python_versions_is_stem_compatible_with`
+ * :ref:`how_do_i_validate_the_pgp_signature`
  * :ref:`can_i_interact_with_tors_controller_interface_directly`
  * :ref:`are_there_any_other_controller_libraries`
  * :ref:`what_license_is_stem_under`
@@ -587,7 +588,7 @@ To start hacking on Stem please do the following and don't 
hesitate to let me
 know if you get stuck or would like to discuss anything!
 
 #. Clone our `git `_ repository: **git clone 
https://git.torproject.org/stem.git**
-#. Get our test dependencies: **sudo pip install mock pycodestyle pyflakes 
mypy**.
+#. Get our test dependencies: **sudo pip install mock pyflakes pycodestyle 
mypy**.
 #. Find a `bug or feature `_ that 
sounds interesting.
 #. When you have something that you would like to contribute back do the 
following...
 
@@ -639,9 +640,9 @@ See ``run_tests.py --help`` for more usage information.
 How can I test compatibility with multiple python versions?
 ---
 
-Stem supports python versions 2.6 and above, including the 3.x series. You can
-test all versions of python you currently have installed on your system with
-`tox `_. If you're using a Debian based system this
+Stem supports python versions 3.6 and above. You can test all versions of
+python you currently have installed on your system with `tox
+`_. If you're using a Debian based system this
 can be as simple as...
 
 ::
@@ -682,8 +683,14 @@ example...
 How do I build the site?
 
 
-If you have `Sphinx `_ version 1.3 or later installed
-then building our site is as easy as...
+To build Stem's website install `Sphinx `_ with its
+`typehint plugin `_...
+
+::
+
+  ~$ sudo pip install sphinx sphinx-autodoc-typehints
+
+Then simply run **make html** within our **docs** directory...
 
 ::
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test retrieving HS client name

2020-10-22 Thread atagar
commit 831dd0515d881248150342c8f4a37e2c51ee0bc3
Author: Damian Johnson 
Date:   Thu Oct 22 15:01:26 2020 -0700

Test retrieving HS client name

The issue that prevented us from testing this was fixed...

  19:28 <+atagar> dgoulet: What is the status of
https://gitlab.torproject.org/tpo/core/tor/-/issues/40089 ? The last
comment discusses another review, but then the 'Needs Review' tag was
removed.
  19:29 <+dgoulet> atagar: so that has been merged upstream it appears
and waiting for backport down to 043
  19:31 <+atagar> Ahh, great - thanks. Per chance do you know what tor
version has the fix? If so then I can check for it in our tests

(https://gitweb.torproject.org/stem.git/tree/test/integ/control/controller.py#n1650).
  19:34 <+dgoulet> atagar: not sure exactly which one but I think 0.4.4.5 +
  19:36 <+atagar> Thanks, I'll conditional the assertion on that version.
If it makes any test runs sad just let me know.
  19:36 <+dgoulet> ack thanks
---
 test/integ/control/controller.py | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index 553b1a4e..a2cc175d 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -1647,13 +1647,10 @@ class TestController(unittest.TestCase):
   self.assertEqual('x25519', credential.key_type)
   self.assertEqual([], credential.flags)
 
-  # TODO: We should assert our client_name's value...
-  #
-  #   self.assertEqual('StemInteg', credential.client_name)
-  #
-  # ... but that's broken within tor...
-  #
-  #   https://gitlab.torproject.org/tpo/core/tor/-/issues/40089
+  # client names were fixed by 
https://gitlab.torproject.org/tpo/core/tor/-/issues/40089
+
+  if test.tor_version() >= stem.version.Version('0.4.4.5'):
+self.assertEqual('StemInteg', credential.client_name)
 
   # deregister authentication credentials
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Static check fixes

2020-10-17 Thread atagar
commit c6952feecfaef195c6ef6123f5f08ddd770c6aeb
Author: Damian Johnson 
Date:   Sat Oct 17 16:06:17 2020 -0700

Static check fixes

Upgrading to pycodestyle 2.6.0 produced a few new warnings...

  STATIC CHECKS
  * /home/atagar/Desktop/stem/stem/descriptor/certificate.py
line 257  - undefined name 'cryptography'| def 
__init__(self, cert_type: Optional['stem.client.datatype.CertType'] = None, 
expiration: Optional[datetime.datetime] = None, key_type: Optional[int] = None, 
key: Optional[bytes] = None, extensions: 
Optional[Sequence['stem.descriptor.certificate.Ed25519Extension']] = None, 
signature: Optional[bytes] = None, signing_key: 
Optional['cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey'] 
= None) -> None:  # type: ignore

  * /home/atagar/Desktop/stem/stem/descriptor/hidden_service.py
line 288  - E741 ambiguous variable name 'l' | link_specifiers 
= link_count + b''.join([l.pack() for l in self.link_specifiers])

  * /home/atagar/Desktop/stem/stem/interpreter/commands.py
line 272  - E741 ambiguous variable name 'l' | lines += 
[format(l, *STANDARD_OUTPUT) for l in str(desc).splitlines()]

  * /home/atagar/Desktop/stem/stem/util/__init__.py
line 84   - undefined name 'cryptography'| def 
_pubkey_bytes(key: 
Union['cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey', 
'cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey', 
'cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey', 
'cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey']) -> bytes:  
# type: ignore

  * /home/atagar/Desktop/stem/test/unit/response/events.py
line 540  - 'stem.control.Controller' imported but unused | from 
stem.control import Controller, EventType

  * stem/client/__init__.py
line 322  - unused 'type: ignore' comment

  * stem/control.py
line 2493 - Unpacking a string is disallowed  [misc]
line 2511 - Unpacking a string is disallowed  [misc]
line 2516 - Unpacking a string is disallowed  [misc]

  * stem/directory.py
line 270  - Unpacking a string is disallowed  [misc]
line 271  - Unpacking a string is disallowed  [misc]
line 436  - Unpacking a string is disallowed  [misc]
---
 stem/client/__init__.py   |  2 +-
 stem/control.py   | 12 +++-
 stem/descriptor/hidden_service.py |  2 +-
 stem/directory.py |  6 +++---
 stem/interpreter/commands.py  |  2 +-
 test/settings.cfg |  2 ++
 test/unit/response/events.py  |  2 +-
 7 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 877d60e2..5453f1f2 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -319,7 +319,7 @@ class Circuit(object):
 except ImportError:
   raise ImportError('Circuit construction requires the cryptography 
module')
 
-ctr = modes.CTR(ZERO * (algorithms.AES.block_size // 8))  # type: ignore
+ctr = modes.CTR(ZERO * (algorithms.AES.block_size // 8))
 
 self.relay = relay
 self.id = circ_id
diff --git a/stem/control.py b/stem/control.py
index b889b801..91d1b3ed 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -2488,9 +2488,11 @@ class Controller(BaseController):
 query_comp = ['RESETCONF' if reset else 'SETCONF']
 
 if isinstance(params, dict):
-  params = list(params.items())
+  params_list = list(params.items())
+else:
+  params_list = params  # type: ignore # type: Sequence[Tuple[str, 
Union[str, Sequence[str
 
-for param, value in params:
+for param, value in params_list:
   if isinstance(value, str):
 query_comp.append('%s="%s"' % (param, value.strip()))
   elif isinstance(value, collections.Iterable):
@@ -2508,12 +2510,12 @@ class Controller(BaseController):
 
   if self.is_caching_enabled():
 # clear cache for params; the CONF_CHANGED event will set cache for 
changes
-to_cache = dict((k.lower(), None) for k, v in params)
+to_cache = dict((k.lower(), None) for k, v in params_list)
 self._set_cache(to_cache, 'getconf')
-self._confchanged_cache_invalidation(dict(params))
+self._confchanged_cache_invalidation(dict(params_list))
 else:
   log.debug('%s (failed, code: %s, message: %s)' % (query, response.code, 
response.message))
-  immutable_params = [k for k, v in params if 
stem.util.str_tools._to_unicode(k).lower() in IMMUTABLE_CONFIG_OPTIONS]
+  immutable_params = [k for k, v in params_list if 
stem.util.str_tools._to_unicode(k).lower() in IMMUTABLE_CONFIG_OPTIONS]
 
   if immutable_params:
 raise stem.InvalidArguments(message = "%s cannot be changed while 
tor's running" % ', '.join(sorted(immutable_params)), arguments = 
immutable

[tor-commits] [stem/master] Avoid 'never awaited' test warnings

2020-10-17 Thread atagar
commit d018d6e29d62045e973c11dfebbac245fed3b51e
Author: Damian Johnson 
Date:   Sat Oct 17 15:48:24 2020 -0700

Avoid 'never awaited' test warnings

When running our tests with Python 3.8.5 I'm getting the following 
warnings...

/home/atagar/Desktop/stem/test/unit/response/events.py:553: 
RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited
  controller.authenticate()
RuntimeWarning: Enable tracemalloc to get the object allocation 
traceback

Our mock spec doesn't provide anything here, so simply omitting it to 
silence
these.
---
 test/unit/response/events.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/unit/response/events.py b/test/unit/response/events.py
index 33557874..f72a92bb 100644
--- a/test/unit/response/events.py
+++ b/test/unit/response/events.py
@@ -548,7 +548,7 @@ class TestEvents(unittest.TestCase):
 print_bw(_get_event('650 BW 15 25'))
 time.sleep(0.0005)
 
-controller = Mock(spec = Controller)
+controller = Mock()
 
 controller.authenticate()
 controller.add_event_listener(print_bw, EventType.BW)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] GETINFO ip-to-country error

2020-10-17 Thread atagar
commit 99396db33e19bfa3f046382cea0600983a15ea33
Author: Damian Johnson 
Date:   Thu Oct 15 16:28:58 2020 -0700

GETINFO ip-to-country error

Oops, forgot to await one of our internal coroutine calls...

  stem/control.py:1236: RuntimeWarning: coroutine 'Controller.get_info' was 
never awaited
---
 stem/control.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/stem/control.py b/stem/control.py
index 9a387f55..b889b801 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -1233,7 +1233,7 @@ class Controller(BaseController):
   param_set = set(params)
 
 for param in param_set:
-  if param.startswith('ip-to-country/') and param != 
'ip-to-country/0.0.0.0' and self.get_info('ip-to-country/ipv4-available', '0') 
!= '1':
+  if param.startswith('ip-to-country/') and param != 
'ip-to-country/0.0.0.0' and await self.get_info('ip-to-country/ipv4-available', 
'0') != '1':
 raise stem.ProtocolError('Tor geoip database is unavailable')
   elif param == 'address' and self._last_address_exc:
 raise self._last_address_exc  # we already know we can't resolve an 
address



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Normalize label input arguments

2020-10-17 Thread atagar
commit c90e87ca9a8b70319a58dee7e328f8af00d3
Author: Damian Johnson 
Date:   Sat Oct 17 16:37:51 2020 -0700

Normalize label input arguments

Functions like size_label() and time_label() are documented as taking an int
argument, but getting a float shouldn't make them choke. Especially in such 
an
unhelpful way...

  ==
  ERROR: test_time_label
  Checks the time_label() function.
  --
  Traceback (most recent call last):
File "/home/atagar/Desktop/stem/test/unit/util/str_tools.py", line 99, 
in test_time_label
  self.assertEqual('0s', str_tools.time_label(0.1))
File "/home/atagar/Desktop/stem/stem/util/str_tools.py", line 366, in 
time_label
  return _get_label(TIME_UNITS, seconds, decimal, is_long)
    File "/home/atagar/Desktop/stem/stem/util/str_tools.py", line 595, in 
_get_label
  raise ValueError('BUG: %s should always be divisible by a unit (%s)' 
% (count, str(units)))
  ValueError: BUG: 0.1 should always be divisible by a unit (((86400.0, 
'd', ' day'), (3600.0, 'h', ' hour'), (60.0, 'm', ' minute'), (1.0, 's', ' 
second')))
---
 stem/util/str_tools.py  | 35 ---
 test/unit/util/str_tools.py |  1 +
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/stem/util/str_tools.py b/stem/util/str_tools.py
index 64bcfc46..9803d437 100644
--- a/stem/util/str_tools.py
+++ b/stem/util/str_tools.py
@@ -329,6 +329,9 @@ def size_label(byte_count: int, decimal: int = 0, is_long: 
bool = False, is_byte
   :returns: **str** with human readable representation of the size
   """
 
+  if isinstance(byte_count, float):
+byte_count = int(byte_count)
+
   if is_bytes:
 return _get_label(SIZE_UNITS_BYTES, byte_count, decimal, is_long, round)
   else:
@@ -363,6 +366,9 @@ def time_label(seconds: int, decimal: int = 0, is_long: 
bool = False) -> str:
   :returns: **str** with human readable representation of the time
   """
 
+  if isinstance(seconds, float):
+seconds = int(seconds)
+
   return _get_label(TIME_UNITS, seconds, decimal, is_long)
 
 
@@ -386,6 +392,9 @@ def time_labels(seconds: int, is_long: bool = False) -> 
Sequence[str]:
   :returns: **list** of strings with human readable representations of the time
   """
 
+  if isinstance(seconds, float):
+seconds = int(seconds)
+
   time_labels = []
 
   for count_per_unit, _, _ in TIME_UNITS:
@@ -416,6 +425,9 @@ def short_time_label(seconds: int) -> str:
   :raises: **ValueError** if the input is negative
   """
 
+  if isinstance(seconds, float):
+seconds = int(seconds)
+
   if seconds < 0:
 raise ValueError("Input needs to be a non-negative integer, got '%i'" % 
seconds)
 
@@ -560,35 +572,36 @@ def _get_label(units: Sequence[Tuple[float, str, str]], 
count: int, decimal: int
 
   # formatted string for the requested number of digits
   label_format = '%%.%if' % decimal
+  remainder = count
 
-  if count < 0:
+  if remainder < 0:
 label_format = '-' + label_format
-count = abs(count)
-  elif count == 0:
+remainder = abs(remainder)
+  elif remainder == 0:
 units_label = units[-1][2] + 's' if is_long else units[-1][1]
 return '%s%s' % (label_format % count, units_label)
 
   for count_per_unit, short_label, long_label in units:
-if count >= count_per_unit:
+if remainder >= count_per_unit:
   if not round:
-# Rounding down with a '%f' is a little clunky. Reducing the count so
-# it'll divide evenly as the rounded down value.
+# Rounding down with a '%f' is a little clunky. Reducing the remainder
+# so it'll divide evenly as the rounded down value.
 
-count -= count % (count_per_unit / (10 ** decimal))
+remainder -= remainder % (count_per_unit / (10 ** decimal))
 
-  count_label = label_format % (count / count_per_unit)
+  count_label = label_format % (remainder / count_per_unit)
 
   if is_long:
 # Pluralize if any of the visible units make it greater than one. For
 # instance 1.0003 is plural but 1.000 isn't.
 
 if decimal > 0:
-  is_plural = count > count_per_unit
+  is_plural = remainder > count_per_unit
 else:
-  is_plural = count >= count_per_unit * 2
+  is_plural = remainder >= count_per_unit * 2
 
 return count_label + long_label + ('s' if is_plural else '')
   else:
 return count_label + short_label
 
-  raise ValueError('BUG: value should always be divisible by a unit (%s)' % 
str(units))
+  raise ValueError('BUG: %s should always be divisible by a unit (%s)' % 
(count, str(units)))
diff --git a/test/unit/util/str_tools.py b/test/unit/util/str_tools.

[tor-commits] [nyx/master] Replace deprecated LogBuffer

2020-10-16 Thread atagar
commit 3f9950051e67c1ef38fd7799a3646308082d58b1
Author: Damian Johnson 
Date:   Thu Oct 15 15:45:28 2020 -0700

Replace deprecated LogBuffer

Stem 2.x drops deprecated classes. As a result we error with...

  Traceback (most recent call last):
File "./run_nyx", line 7, in 
  import nyx
File "/home/atagar/Desktop/nyx/nyx/__init__.py", line 779, in 
  import nyx.panel.log
    File "/home/atagar/Desktop/nyx/nyx/panel/log.py", line 69, in 
  NYX_LOGGER = log.LogBuffer(log.Runlevel.DEBUG, yield_records = True)
  AttributeError: module 'stem.util.log' has no attribute 'LogBuffer'

This was removed in stem commit 76b6b49. Fortunately it's a simple class to
replace.
---
 nyx/panel/log.py | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/nyx/panel/log.py b/nyx/panel/log.py
index 76dd20c..030be38 100644
--- a/nyx/panel/log.py
+++ b/nyx/panel/log.py
@@ -9,6 +9,9 @@ regular expressions.
 
 import functools
 import os
+import logging
+import logging.handlers
+import queue
 import time
 
 import stem.response.events
@@ -66,7 +69,10 @@ CONTENT_HEIGHT_REDRAW_THRESHOLD = 3
 # to make our LogPanel when curses initializes.
 
 stem_logger = log.get_logger()
-NYX_LOGGER = log.LogBuffer(log.Runlevel.DEBUG, yield_records = True)
+NYX_LOG_BUFFER = queue.Queue()
+
+NYX_LOGGER = logging.handlers.QueueHandler(NYX_LOG_BUFFER)
+NYX_LOGGER.setLevel(logging.DEBUG)
 stem_logger.addHandler(NYX_LOGGER)
 
 
@@ -123,8 +129,8 @@ class LogPanel(nyx.panel.DaemonPanel):
 
 # merge NYX_LOGGER into us, and listen for its future events
 
-for event in NYX_LOGGER:
-  self._register_nyx_event(event)
+while not NYX_LOG_BUFFER.empty():
+  self._register_nyx_event(NYX_LOG_BUFFER.get_nowait())
 
 NYX_LOGGER.emit = self._register_nyx_event
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] Drop is_geoip_unavailable() usage

2020-10-16 Thread atagar
commit 8d49aa9c29a88e53c5944c683f28137a7d733787
Author: Damian Johnson 
Date:   Fri Oct 16 15:48:10 2020 -0700

Drop is_geoip_unavailable() usage

Another deprecated method that has been removed from Stem. This fixes...

  Traceback (most recent call last):
File "./run_nyx", line 14, in 
  nyx.main()
File "/home/atagar/Desktop/nyx/nyx/__init__.py", line 199, in main
  nyx.starter.main()
    File "/home/atagar/Desktop/nyx/stem/util/conf.py", line 287, in wrapped
  return func(*args, config = config, **kwargs)
File "/home/atagar/Desktop/nyx/nyx/starter.py", line 128, in main
  nyx.curses.start(nyx.draw_loop, acs_support = 
config.get('acs_support', True), transparent_background = True, cursor = False)
File "/home/atagar/Desktop/nyx/nyx/curses.py", line 219, in start
  curses.wrapper(_wrapper)
File "/usr/lib/python3.8/curses/__init__.py", line 105, in wrapper
  return func(stdscr, *args, **kwds)
File "/home/atagar/Desktop/nyx/nyx/curses.py", line 217, in _wrapper
  function()
File "/home/atagar/Desktop/nyx/nyx/__init__.py", line 257, in draw_loop
  interface.redraw(force = not key.is_null())
File "/home/atagar/Desktop/nyx/nyx/__init__.py", line 733, in redraw
  panel.redraw(force = force, top = occupied)
File "/home/atagar/Desktop/nyx/nyx/panel/__init__.py", line 175, in 
redraw
  self._last_draw_size = nyx.curses.draw(self._draw, top = self._top, 
height = self.get_height(), draw_if_resized = draw_dimension)
File "/home/atagar/Desktop/nyx/nyx/curses.py", line 760, in draw
  func(_Subwindow(subwindow_width, subwindow_height, curses_subwindow))
File "/home/atagar/Desktop/nyx/nyx/panel/connection.py", line 476, in 
_draw
  _draw_line(subwindow, scroll_offset, y, lines[line_number], 
lines[line_number] == selected, subwindow.width - scroll_offset, current_time)
File "/home/atagar/Desktop/nyx/nyx/panel/connection.py", line 608, in 
_draw_line
  x = _draw_address_column(subwindow, x, y, line, attr)
File "/home/atagar/Desktop/nyx/nyx/panel/connection.py", line 630, in 
_draw_address_column
  elif not tor_controller().is_geoip_unavailable() and not 
line.entry.is_private():
  AttributeError: 'Controller' object has no attribute 
'is_geoip_unavailable'
---
 nyx/panel/connection.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/nyx/panel/connection.py b/nyx/panel/connection.py
index a97d28f..ce5d57b 100644
--- a/nyx/panel/connection.py
+++ b/nyx/panel/connection.py
@@ -627,11 +627,11 @@ def _draw_address_column(subwindow, x, y, line, attr):
 
   if purpose:
 dst += ' (%s)' % str_tools.crop(purpose, 26 - len(dst) - 3)
-elif not tor_controller().is_geoip_unavailable() and not 
line.entry.is_private():
+elif tor_controller().get_info('ip-to-country/ipv4-available', '0') == '1' 
and not line.entry.is_private():
   dst += ' (%s)' % (line.locale if line.locale else '??')
 
   src = '%-21s' % src
-  dst = '%-21s' % dst if tor_controller().is_geoip_unavailable() else '%-26s' 
% dst
+  dst = '%-21s' % dst if 
tor_controller().get_info('ip-to-country/ipv4-available', '0') != '1' else 
'%-26s' % dst
 
   if line.entry.get_type() in (Category.INBOUND, Category.SOCKS, 
Category.CONTROL):
 dst, src = src, dst

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] Documented graph_bound incorrect

2020-10-11 Thread atagar
commit c099fe31266bc68f8551f93db9f5a95a6944c303
Author: Damian Johnson 
Date:   Sun Oct 11 15:23:00 2020 -0700

Documented graph_bound incorrect

Oops, inverted the words. Caught thanks to saizai...

  https://github.com/torproject/nyx/issues/22
---
 web/index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/web/index.html b/web/index.html
index a980f7c..f214a36 100644
--- a/web/index.html
+++ b/web/index.html
@@ -682,7 +682,7 @@ logged_events BW, NOTICE, WARN, ERR
 
 
   graph_bound
-  max_local
+  local_max
   Bounding for the graph min and max. Options are...
 
   global_max - global maximum

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [policies/master] Drop trac activity script

2020-10-04 Thread atagar
commit 1adccd8c6c2d7b2a85d0d377fb0a48f6f7fbb628
Author: Damian Johnson 
Date:   Sun Oct 4 14:40:54 2020 -0700

Drop trac activity script

TPI moved from Trac to Gitlab so this script is no longer useful.
---
 scripts/trac_activity.py | 27 ---
 1 file changed, 27 deletions(-)

diff --git a/scripts/trac_activity.py b/scripts/trac_activity.py
deleted file mode 100644
index ef09dfa..000
--- a/scripts/trac_activity.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import collections
-import re
-import urllib
-
-TICKETS_CREATED = 
'https://trac.torproject.org/projects/tor/timeline?daysback=180=on=Update'
-TICKETS_UPDATED = 
'https://trac.torproject.org/projects/tor/timeline?daysback=180_details=on=Update'
-WIKI_UPDATES = 
'https://trac.torproject.org/projects/tor/timeline?daysback=180=on=Update'
-
-USER_ACTION = re.compile('by (\S+)')
-
-for title, url in (('Tickets Created', TICKETS_CREATED), ('Tickets Updated', 
TICKETS_UPDATED), ('Wiki Edits', WIKI_UPDATES)):
-  request = urllib.urlopen(url)
-  user_edits = filter(lambda user: user != 'trac' and user != 'cypherpunks', 
USER_ACTION.findall(request.read()))
-
-  print('=' * 60)
-  print(title)
-  print('=' * 60)
-  print('')
-
-  threshold = 0.01 * len(user_edits)  # only show results if it's at least 1% 
to avoid long tail
-
-  for user, count in sorted(collections.Counter(user_edits).items(), key = 
lambda entry: entry[1], reverse = True):
-if count >= threshold:
-  print(' * %s %s' % (count, user))
-
-  print('')
-

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test relay_connections example

2020-10-02 Thread atagar
commit 386b9ba692d21074b4aeac50591bacd889d93581
Author: Damian Johnson 
Date:   Thu Oct 1 17:15:56 2020 -0700

Test relay_connections example
---
 docs/_static/example/relay_connections.py | 10 ++--
 test/unit/examples.py | 78 +--
 2 files changed, 78 insertions(+), 10 deletions(-)

diff --git a/docs/_static/example/relay_connections.py 
b/docs/_static/example/relay_connections.py
index 26f59f4c..90539f89 100644
--- a/docs/_static/example/relay_connections.py
+++ b/docs/_static/example/relay_connections.py
@@ -9,7 +9,7 @@ import stem.util.str_tools
 from stem.control import Listener
 from stem.util.connection import get_connections, port_usage, 
is_valid_ipv4_address
 
-HEADER_LINE = " {version}   uptime: {uptime}   flags: {flags}\n"
+HEADER_LINE = ' {version}   uptime: {uptime}   flags: {flags}\n'
 
 DIV = '+%s+%s+%s+' % ('-' * 30, '-' * 6, '-' * 6)
 COLUMN = '| %-28s | %4s | %4s |'
@@ -23,11 +23,11 @@ OUTBOUND_EXIT = 'Outbound exit traffic'
 OUTBOUND_UNKNOWN = 'Outbound uncategorized'
 
 
-def main():
+def main(args = None):
   parser = argparse.ArgumentParser()
-  parser.add_argument("--ctrlport", help="default: 9051 or 9151")
-  parser.add_argument("--resolver", help="default: autodetected")
-  args = parser.parse_args()
+  parser.add_argument('--ctrlport', help = 'default: 9051 or 9151')
+  parser.add_argument('--resolver', help = 'default: autodetected')
+  args = parser.parse_args(args)
 
   control_port = int(args.ctrlport) if args.ctrlport else 'default'
   controller = stem.connection.connect(control_port = ('127.0.0.1', 
control_port))
diff --git a/test/unit/examples.py b/test/unit/examples.py
index 9d42299d..e1c223bf 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -13,10 +13,11 @@ import unittest
 
 import stem.socket
 import stem.util.system
+import stem.version
 import test
 import test.require
 
-from stem.control import Controller
+from stem.control import Controller, Listener
 from stem.descriptor.bandwidth_file import BandwidthFile
 from stem.descriptor.extrainfo_descriptor import RelayExtraInfoDescriptor
 from stem.descriptor.hidden_service import HiddenServiceDescriptorV2
@@ -26,6 +27,7 @@ from stem.descriptor.server_descriptor import RelayDescriptor
 from stem.directory import DIRECTORY_AUTHORITIES
 from stem.exit_policy import ExitPolicy
 from stem.response import ControlMessage
+from stem.util.connection import Connection
 from unittest.mock import Mock, patch
 
 EXAMPLE_DIR = os.path.join(test.STEM_BASE, 'docs', '_static', 'example')
@@ -36,6 +38,7 @@ UNTESTED = (
 
   'client_usage_using_pycurl',
   'client_usage_using_socksipy',
+  'reading_twitter',
 )
 
 EXPECTED_BANDWIDTH_STATS = """\
@@ -199,6 +202,31 @@ EXPECTED_PERSISTING_A_CONSENSUS = """\
 A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB: caerSidi
 """
 
+EXPECTED_RELAY_CONNECTIONS_HELP = """\
+usage: run_tests.py [-h] [--ctrlport CTRLPORT] [--resolver RESOLVER]
+
+optional arguments:
+  -h, --help   show this help message and exit
+  --ctrlport CTRLPORT  default: 9051 or 9151
+  --resolver RESOLVER  default: autodetected
+"""
+
+EXPECTED_RELAY_CONNECTIONS = """\
+ 1.2.3.4   uptime: 00:50   flags: Fast, Stable
+
++--+--+--+
+| Type | IPv4 | IPv6 |
++--+--+--+
+| Inbound to our ORPort|1 |0 |
+| Inbound to our DirPort   |2 |0 |
+| Inbound to our ControlPort   |1 |0 |
+| Outbound uncategorized   |1 |0 |
++--+--+--+
+| Total|5 |0 |
++------+--+--+
+
+"""
+
 EXPECTED_RUNNING_HIDDEN_SERVICE = """\
  * Connecting to tor
  * Creating our hidden service in /home/atagar/.tor/hello_world
@@ -794,11 +822,51 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual('4F0C867DF0EF68160568C826838F482CEA7CFE44\n', 
stdout_mock.getvalue())
 
-  def test_reading_twitter(self):
-pass
+  @patch('sys.exit', Mock())
+  @patch('time.time', Mock(return_value = 100))
+  @patch('stem.util.system.start_time', Mock(return_value = 50))
+  @patch('stem.util.connection.get_connections')
+  @patch('stem.connection.connect')
+  def test_relay_connections(self, connect_mock, get_connections_mock):
+import relay_connections
 
-  def test_relay_connections(self):
-pass
+with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
+  connect_mock.return_value = None
+
+  relay_connections.main(['--help'])
+  self.assertEqual(EXPECTED_RELAY_CONNECTIONS_HELP, stdout_mock.getvalue())
+
+with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
+  consensus_desc = RouterStatusEntryV2.create({
+'r': 'cae

[tor-commits] [stem/master] Test utilities example

2020-10-02 Thread atagar
commit d0c95c2b4817cc8bc7a5847d6f139fe467070438
Author: Damian Johnson 
Date:   Fri Oct 2 13:32:52 2020 -0700

Test utilities example
---
 test/unit/examples.py | 27 ---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 5e2bbc78..8d0f3b3e 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -27,7 +27,7 @@ from stem.descriptor.server_descriptor import RelayDescriptor
 from stem.directory import DIRECTORY_AUTHORITIES
 from stem.exit_policy import ExitPolicy
 from stem.response import ControlMessage
-from stem.util.connection import Connection
+from stem.util.connection import Connection, Resolver
 from unittest.mock import Mock, patch
 
 EXAMPLE_DIR = os.path.join(test.STEM_BASE, 'docs', '_static', 'example')
@@ -240,6 +240,16 @@ EXPECTED_TOR_DESCRIPTORS = """\
 3. speedyexit (102.13 KB/s)
 """
 
+EXPECTED_UTILITIES = """\
+Our platform supports connection resolution via: netstat (picked netstat)
+Tor is running with pid 12345
+
+Connections:
+
+  17.17.17.17:4369 => 34.34.34.34:8738
+  18.18.18.18:443 => 35.35.35.35:4281
+"""
+
 EXPECTED_VOTES_BY_BANDWIDTH_AUTHORITIES = """\
 Getting gabelmoo's vote from 
http://131.188.40.189:80/tor/status-vote/current/authority:
   5935 measured entries and 1332 unmeasured
@@ -967,8 +977,19 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual(EXPECTED_TOR_DESCRIPTORS, stdout_mock.getvalue())
 
-  def test_utilities(self):
-pass
+  @patch('stem.util.connection.system_resolvers', Mock(return_value = 
[Resolver.NETSTAT]))
+  @patch('stem.util.system.pid_by_name', Mock(return_value = [12345]))
+  @patch('stem.util.connection.get_connections')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_utilities(self, stdout_mock, get_connections_mock):
+get_connections_mock.return_value = [
+  Connection('17.17.17.17', 4369, '34.34.34.34', 8738, 'tcp', False),
+  Connection('18.18.18.18', 443, '35.35.35.35', 4281, 'tcp', False),
+]
+
+import utilities
+
+self.assertEqual(EXPECTED_UTILITIES, stdout_mock.getvalue())
 
   def test_validate_descriptor_content(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] connect() broke Controller's iterator methods

2020-10-02 Thread atagar
commit e1137067509f005504731157297096f9890b5f7d
Author: Damian Johnson 
Date:   Fri Oct 2 15:52:48 2020 -0700

connect() broke Controller's iterator methods

Damn I need to rewrite our connection module. As indicated by the TODO 
comment,
this method copies some of Synchronous' init. No surprise then that when I
fixed Synchronous' iterators the fix didn't get propagated here.

Caught thanks to toralf noticing that our relay_connections.py example 
didn't
work...

  % python3.7 relay_connections.py
   0.4.5.0-alpha-dev   uptime: 14:27   flags: none

  Traceback (most recent call last):
File "relay_connections.py", line 130, in 
  main()
File "relay_connections.py", line 50, in main
  for desc in controller.get_network_statuses():
  TypeError: 'async_generator' object is not iterable
---
 stem/connection.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/stem/connection.py b/stem/connection.py
index 68cfda45..005949ef 100644
--- a/stem/connection.py
+++ b/stem/connection.py
@@ -305,7 +305,7 @@ def connect(control_port: Tuple[str, Union[str, int]] = 
('127.0.0.1', 'default')
 pass
   elif isinstance(func, unittest.mock.Mock) and 
inspect.iscoroutinefunction(func.side_effect):
 setattr(connection, name, 
functools.partial(connection._run_async_method, name))
-  elif inspect.ismethod(func) and inspect.iscoroutinefunction(func):
+  elif inspect.ismethod(func) and (inspect.iscoroutinefunction(func) or 
inspect.isasyncgenfunction(func)):
 setattr(connection, name, 
functools.partial(connection._run_async_method, name))
 
 return connection



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test words_with example

2020-10-02 Thread atagar
commit 740a22364f55ea6566c536f0891bc279d04cb91a
Author: Damian Johnson 
Date:   Fri Oct 2 14:09:41 2020 -0700

Test words_with example
---
 docs/_static/example/words_with.py | 12 
 test/unit/examples.py  | 20 +---
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/docs/_static/example/words_with.py 
b/docs/_static/example/words_with.py
index ae616f9e..b6670c51 100644
--- a/docs/_static/example/words_with.py
+++ b/docs/_static/example/words_with.py
@@ -18,7 +18,7 @@ def get_words_with(target, attr):
   word_matcher = re.compile('(.*)(%s)(.*)' % target, re.I)
 
   with open('/etc/dictionaries-common/words') as dictionary_file:
-for word in dictionary_file:
+for word in dictionary_file.readlines():
   match = word_matcher.match(word)
 
   if match:
@@ -29,11 +29,15 @@ def get_words_with(target, attr):
 ))
 
 
-if __name__ == '__main__':
-  target = raw_input("What substring would you like to look for? We'll get 
words containing it: ")
+def main():
+  target = input("What substring would you like to look for? We'll get words 
containing it: ")
   attr = (Attr.BOLD, Color.YELLOW)
 
   print("Words with '%s' include...\n" % term.format(target, *attr))
 
-  for words in itertools.izip_longest(*(get_words_with(target, attr),) * 4):
+  for words in itertools.zip_longest(*(get_words_with(target, attr),) * 4):
 print('%-30s%-30s%-30s%-30s' % tuple([w if w else '' for w in words]))
+
+
+if __name__ == '__main__':
+  main()
diff --git a/test/unit/examples.py b/test/unit/examples.py
index b713932c..faea5e6c 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -28,7 +28,7 @@ from stem.directory import DIRECTORY_AUTHORITIES
 from stem.exit_policy import ExitPolicy
 from stem.response import ControlMessage
 from stem.util.connection import Connection, Resolver
-from unittest.mock import Mock, patch
+from unittest.mock import Mock, mock_open, patch
 
 EXAMPLE_DIR = os.path.join(test.STEM_BASE, 'docs', '_static', 'example')
 DESC_DIR = os.path.join(test.STEM_BASE, 'test', 'unit', 'descriptor', 'data')
@@ -259,6 +259,12 @@ Getting maatuska's vote from 
http://171.25.193.9:443/tor/status-vote/current/aut
   6313 measured entries and 1112 unmeasured
 """
 
+EXPECTED_WORDS_WITH = """\
+Words with 'hel' include...
+
+hello hellena
+"""
+
 
 def _make_circ_event(circ_id, hop1, hop2, hop3):
   path = '$%s=%s,$%s=%s,$%s=%s' % (hop1[0], hop1[1], hop2[0], hop2[1], 
hop3[0], hop3[1])
@@ -1033,5 +1039,13 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual(EXPECTED_VOTES_BY_BANDWIDTH_AUTHORITIES, 
stdout_mock.getvalue())
 
-  def test_words_with(self):
-pass
+  @patch('builtins.input', Mock(return_value = 'hel'))
+  @patch('builtins.open', mock_open(read_data = 'hello\nnope\nhellena'))
+  @patch('stem.util.term.format', Mock(side_effect = lambda msg, *args: msg))
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_words_with(self, stdout_mock):
+import words_with
+
+words_with.main()
+
+self.assertEqual(EXPECTED_WORDS_WITH.rstrip(), 
stdout_mock.getvalue().rstrip())



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test website example code

2020-10-02 Thread atagar
commit 26bf1bb49540c86751e20f133e7c906af92ea742
Merge: ab835c1a e1137067
Author: Damian Johnson 
Date:   Fri Oct 2 16:00:11 2020 -0700

Test website example code

Most examples lacked test coverage. We tested some in 2012 (tutorial.py) and
2014 (tutorial_examples.py), but they weren't updated as new code got added.

Aside from testing and fixing just about everything, this branch asserts 
that
new examples have test coverage so we stay atop this.

 .../example/benchmark_server_descriptor_stem.py|2 +
 docs/_static/example/benchmark_stem.py |   15 +-
 docs/_static/example/check_digests.py  |   19 +-
 docs/_static/example/client_usage_using_pycurl.py  |   10 +-
 .../_static/example/client_usage_using_socksipy.py |6 +-
 docs/_static/example/compare_flags.py  |2 +-
 docs/_static/example/create_descriptor.py  |4 +-
 docs/_static/example/create_descriptor_content.py  |2 +-
 docs/_static/example/current_descriptors.py|4 +-
 docs/_static/example/custom_path_selection.py  |7 +-
 docs/_static/example/descriptor_from_orport.py |4 +-
 .../example/descriptor_from_tor_control_socket.py  |2 +-
 docs/_static/example/download_descriptor.py|   13 +-
 docs/_static/example/ephemeral_hidden_services.py  |6 +-
 docs/_static/example/event_listening.py|   48 +-
 docs/_static/example/exit_used.py  |   17 +-
 docs/_static/example/fibonacci_multiprocessing.py  |   23 +-
 docs/_static/example/fibonacci_threaded.py |   29 +-
 docs/_static/example/hello_world.py|6 +-
 docs/_static/example/list_circuits.py  |6 +-
 docs/_static/example/load_test.py  |   25 -
 docs/_static/example/manual_config_options.py  |7 +-
 docs/_static/example/outdated_relays.py|   10 +-
 .../persisting_a_consensus_with_parse_file.py  |2 +-
 docs/_static/example/reading_twitter.py|   49 +-
 docs/_static/example/relay_connections.py  |   10 +-
 .../example/resuming_ephemeral_hidden_service.py   |6 +-
 docs/_static/example/running_hidden_service.py |8 +-
 .../example/saving_and_loading_descriptors.py  |2 +-
 docs/_static/example/tor_descriptors.py|7 +-
 docs/_static/example/utilities.py  |8 +-
 .../example/votes_by_bandwidth_authorities.py  |2 +-
 docs/_static/example/words_with.py |   12 +-
 docs/tutorials/mirror_mirror_on_the_wall.rst   |3 -
 docs/tutorials/to_russia_with_love.rst |2 +-
 stem/connection.py |2 +-
 stem/descriptor/__init__.py|3 +
 stem/descriptor/server_descriptor.py   |   10 +-
 stem/manual.py |2 +-
 stem/response/events.py|4 +
 test/settings.cfg  |4 +-
 test/task.py   |1 +
 test/unit/__init__.py  |   11 -
 test/unit/doctest.py   |4 +-
 test/unit/examples.py  | 1052 
 test/unit/tutorial.py  |  215 
 test/unit/tutorial_examples.py |  319 --
 47 files changed, 1270 insertions(+), 735 deletions(-)

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Run static checks on examples

2020-10-02 Thread atagar
commit cef22e37c41de84b702e63b38ffaf3404069fefa
Author: Damian Johnson 
Date:   Fri Oct 2 15:08:41 2020 -0700

Run static checks on examples
---
 .../example/benchmark_server_descriptor_stem.py|  2 +
 docs/_static/example/benchmark_stem.py |  6 ++-
 docs/_static/example/check_digests.py  | 10 ++---
 docs/_static/example/client_usage_using_pycurl.py  | 10 ++---
 .../_static/example/client_usage_using_socksipy.py |  6 +--
 docs/_static/example/create_descriptor.py  |  4 +-
 docs/_static/example/current_descriptors.py|  4 +-
 docs/_static/example/custom_path_selection.py  |  3 +-
 docs/_static/example/descriptor_from_orport.py |  4 +-
 .../example/descriptor_from_tor_control_socket.py  |  2 +-
 docs/_static/example/download_descriptor.py|  1 +
 docs/_static/example/ephemeral_hidden_services.py  |  6 +--
 docs/_static/example/event_listening.py|  6 +++
 docs/_static/example/exit_used.py  | 15 +++
 docs/_static/example/fibonacci_multiprocessing.py  |  5 ++-
 docs/_static/example/fibonacci_threaded.py |  5 ++-
 docs/_static/example/hello_world.py|  6 +--
 docs/_static/example/manual_config_options.py  |  5 +--
 docs/_static/example/outdated_relays.py| 10 ++---
 .../persisting_a_consensus_with_parse_file.py  |  2 +-
 docs/_static/example/reading_twitter.py| 49 +-
 .../example/resuming_ephemeral_hidden_service.py   |  4 +-
 docs/_static/example/running_hidden_service.py |  8 ++--
 docs/_static/example/tor_descriptors.py|  7 +++-
 docs/_static/example/utilities.py  |  8 ++--
 .../example/votes_by_bandwidth_authorities.py  |  2 +-
 test/task.py   |  1 +
 27 files changed, 112 insertions(+), 79 deletions(-)

diff --git a/docs/_static/example/benchmark_server_descriptor_stem.py 
b/docs/_static/example/benchmark_server_descriptor_stem.py
index c475652e..5154b6e7 100644
--- a/docs/_static/example/benchmark_server_descriptor_stem.py
+++ b/docs/_static/example/benchmark_server_descriptor_stem.py
@@ -1,6 +1,7 @@
 import time
 import stem.descriptor
 
+
 def measure_average_advertised_bandwidth(path):
   start_time = time.time()
   total_bw, count = 0, 0
@@ -17,5 +18,6 @@ def measure_average_advertised_bandwidth(path):
   print('  Time per server descriptor: %0.5f seconds' % (runtime / count))
   print('')
 
+
 if __name__ == '__main__':
   measure_average_advertised_bandwidth('server-descriptors-2015-11.tar')
diff --git a/docs/_static/example/benchmark_stem.py 
b/docs/_static/example/benchmark_stem.py
index 7094c3dd..ab94d960 100644
--- a/docs/_static/example/benchmark_stem.py
+++ b/docs/_static/example/benchmark_stem.py
@@ -1,6 +1,7 @@
 import time
 import stem.descriptor
 
+
 def measure_average_advertised_bandwidth(path):
   start_time = time.time()
   total_bw, count = 0, 0
@@ -17,6 +18,7 @@ def measure_average_advertised_bandwidth(path):
   print('  Time per server descriptor: %0.5f seconds' % (runtime / count))
   print('')
 
+
 def measure_countries_v3_requests(path):
   start_time = time.time()
   countries, count = set(), 0
@@ -35,6 +37,7 @@ def measure_countries_v3_requests(path):
   print('  Time per extrainfo descriptor: %0.5f seconds' % (runtime / count))
   print('')
 
+
 def measure_average_relays_exit(path):
   start_time = time.time()
   total_relays, exits, consensuses = 0, 0, 0
@@ -56,6 +59,7 @@ def measure_average_relays_exit(path):
   print('  Time per consensus: %0.5f seconds' % (runtime / consensuses))
   print('')
 
+
 def measure_fraction_relays_exit_80_microdescriptors(path):
   start_time = time.time()
   exits, count = 0, 0
@@ -74,9 +78,9 @@ def measure_fraction_relays_exit_80_microdescriptors(path):
   print('  Time per microdescriptor: %0.5f seconds' % (runtime / count))
   print('')
 
+
 if __name__ == '__main__':
   
measure_average_advertised_bandwidth('/home/atagar/Desktop/server-descriptors-2015-11.tar')
   measure_countries_v3_requests('/home/atagar/Desktop/extra-infos-2015-11.tar')
   measure_average_relays_exit('/home/atagar/Desktop/consensuses-2015-11.tar')
   
measure_fraction_relays_exit_80_microdescriptors('/home/atagar/Desktop/microdescs-2015-11.tar')
-
diff --git a/docs/_static/example/check_digests.py 
b/docs/_static/example/check_digests.py
index 93b037c0..2807c4d7 100644
--- a/docs/_static/example/check_digests.py
+++ b/docs/_static/example/check_digests.py
@@ -42,16 +42,16 @@ def validate_relay(fingerprint):
 sys.exit(1)
 
   if router_status_entry.digest == server_desc.digest():
-print("Server descriptor digest is correct")
+print('Server descriptor digest is correct')
   else:
-print("Server descriptor digest invalid, expected %s but is %s" % 
(router_status_entry.digest, server_desc.digest()))
+print('Server descriptor digest invalid, expected %s but is %s' % 
(router_status_entry.digest

[tor-commits] [stem/master] Test read_with_parse_file example

2020-10-02 Thread atagar
commit 5f65f718a15e4c53b6422f89a369db9e95b57fe4
Author: Damian Johnson 
Date:   Tue Sep 29 19:17:07 2020 -0700

Test read_with_parse_file example
---
 test/unit/examples.py | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 6e32a0f2..9d42299d 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -785,8 +785,14 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual('I got a BW event for 15 bytes downloaded and 25 bytes 
uploaded\n', stdout_mock.getvalue())
 
-  def test_read_with_parse_file(self):
-pass
+  @patch('stem.descriptor.parse_file')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_read_with_parse_file(self, stdout_mock, parse_file_mock):
+parse_file_mock.return_value = [RelayDescriptor.create({'fingerprint': 
'4F0C 867D F0EF 6816 0568 C826 838F 482C EA7C FE44'})]
+
+import read_with_parse_file
+
+self.assertEqual('4F0C867DF0EF68160568C826838F482CEA7CFE44\n', 
stdout_mock.getvalue())
 
   def test_reading_twitter(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test validate_descriptor_content example

2020-10-02 Thread atagar
commit 00dd6cdd072ec1ee1ce6788d61236623740bf048
Author: Damian Johnson 
Date:   Fri Oct 2 13:35:23 2020 -0700

Test validate_descriptor_content example
---
 test/unit/examples.py | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 8d0f3b3e..b713932c 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -991,8 +991,16 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual(EXPECTED_UTILITIES, stdout_mock.getvalue())
 
-  def test_validate_descriptor_content(self):
-pass
+  @patch('stem.descriptor.parse_file')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_validate_descriptor_content(self, stdout_mock, parse_file_mock):
+parse_file_mock.return_value = [RouterStatusEntryV3.create({
+  'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 71.35.150.29 9001 0',
+})]
+
+import validate_descriptor_content
+
+self.assertEqual('found relay caerSidi 
(A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
 
   @patch('stem.descriptor.remote.DescriptorDownloader.query')
   @patch('stem.directory.Authority.from_cache')



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Speed up test_download_descriptor

2020-10-02 Thread atagar
commit e32f8f75ef31e7165344534dbb56e5fb1c2674a8
Author: Damian Johnson 
Date:   Fri Oct 2 14:42:59 2020 -0700

Speed up test_download_descriptor

Our '--help' assertion pointlessly downloaded server descriptors (since we
negate sys.exit). This reduces this test's runtime from 211 to 1 ms.
---
 test/unit/examples.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index faea5e6c..2d6d2eec 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -606,8 +606,9 @@ class TestExamples(unittest.TestCase):
 import download_descriptor
 
 with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
-  download_descriptor.main(['--help'])
-  self.assertTrue(stdout_mock.getvalue().startswith("Downloads a 
descriptor through Tor's ORPort"))
+  with patch('stem.descriptor.remote.get_server_descriptors', 
_download_of([])):
+download_descriptor.main(['--help'])
+self.assertTrue(stdout_mock.getvalue().startswith("Downloads a 
descriptor through Tor's ORPort"))
 
 with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
   download_descriptor.main(['--type', 'kaboom'])



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test saving_and_loading_descriptors example

2020-10-02 Thread atagar
commit 950d26d7ea8df575499def8ba1e948a547b6af65
Author: Damian Johnson 
Date:   Fri Oct 2 12:39:45 2020 -0700

Test saving_and_loading_descriptors example
---
 docs/_static/example/saving_and_loading_descriptors.py |  2 +-
 test/unit/examples.py  | 12 +++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/docs/_static/example/saving_and_loading_descriptors.py 
b/docs/_static/example/saving_and_loading_descriptors.py
index 42e3ffe1..9112360a 100644
--- a/docs/_static/example/saving_and_loading_descriptors.py
+++ b/docs/_static/example/saving_and_loading_descriptors.py
@@ -2,5 +2,5 @@ import stem.descriptor.remote
 
 server_descriptors = stem.descriptor.remote.get_server_descriptors().run()
 
-with open('/tmp/descriptor_dump', 'wb') as descriptor_file:
+with open('/tmp/descriptor_dump', 'w') as descriptor_file:
   descriptor_file.write(''.join(map(str, server_descriptors)))
diff --git a/test/unit/examples.py b/test/unit/examples.py
index 0b66c124..73bae36c 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -918,7 +918,17 @@ class TestExamples(unittest.TestCase):
   sys.modules = original_modules
 
   def test_saving_and_loading_descriptors(self):
-pass
+server_desc = RelayDescriptor.create({'router': 'caerSidi 71.35.133.197 
9001 0 0'})
+
+with patch('stem.descriptor.remote.get_server_descriptors', 
_download_of(server_desc)):
+  try:
+import saving_and_loading_descriptors
+
+with open('/tmp/descriptor_dump') as descriptor_file:
+  self.assertTrue(descriptor_file.read().startswith('router caerSidi 
71.35.133.197'))
+  finally:
+if os.path.exists('/tmp/descriptor_dump'):
+  os.remove('/tmp/descriptor_dump')
 
   def test_slow_listener(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test create_descriptor example

2020-10-02 Thread atagar
commit a72cb09d271dd04b5f81b91272a0abfbbcdc867a
Author: Damian Johnson 
Date:   Mon Sep 28 16:06:02 2020 -0700

Test create_descriptor example
---
 docs/_static/example/create_descriptor_content.py |  2 +-
 test/unit/examples.py | 22 ++
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/docs/_static/example/create_descriptor_content.py 
b/docs/_static/example/create_descriptor_content.py
index e4a9f2b8..b69ea768 100644
--- a/docs/_static/example/create_descriptor_content.py
+++ b/docs/_static/example/create_descriptor_content.py
@@ -1,3 +1,3 @@
 from stem.descriptor.server_descriptor import RelayDescriptor
 
-print(RelayDescriptor.content({'router': 'demo 127.0.0.1 80 0 0'}))
+print(RelayDescriptor.content({'router': 'demo 127.0.0.1 80 0 
0'}).decode('utf-8'))
diff --git a/test/unit/examples.py b/test/unit/examples.py
index dc9fc242..1b85c297 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -396,11 +396,25 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual(EXPECTED_COMPARE_FLAGS, stdout_mock.getvalue())
 
-  def test_create_descriptor(self):
-pass
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_create_descriptor(self, stdout_mock):
+import create_descriptor
 
-  def test_create_descriptor_content(self):
-pass
+# First line is randomized, for example...
+#
+#   Unnamed566296572314 (226.149.46.74:9001)
+#   demo (127.0.0.1:80)
+
+lines = stdout_mock.getvalue().splitlines()
+
+self.assertTrue(lines[0].startswith('Unnamed'))
+self.assertEqual('demo (127.0.0.1:80)', lines[1])
+
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_create_descriptor_content(self, stdout_mock):
+import create_descriptor_content
+
+self.assertTrue(stdout_mock.getvalue().startswith('router demo 127.0.0.1 
80 0 0\npublish'))
 
   @patch('stem.descriptor.remote.DescriptorDownloader')
   @patch('sys.stdout', new_callable = io.StringIO)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test that all examples are referenced

2020-10-02 Thread atagar
commit ef7416255976b2885733c170a6bde0263a239254
Author: Damian Johnson 
Date:   Tue Sep 29 16:48:37 2020 -0700

Test that all examples are referenced

Our unused load_test.py makes it clear that we should check that all our
examples are cited by the website. I can see myself making that mistake 
again.
---
 docs/tutorials/to_russia_with_love.rst |  2 +-
 stem/manual.py |  2 +-
 test/unit/examples.py  | 35 --
 3 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/docs/tutorials/to_russia_with_love.rst 
b/docs/tutorials/to_russia_with_love.rst
index fc1b4d2c..af94185a 100644
--- a/docs/tutorials/to_russia_with_love.rst
+++ b/docs/tutorials/to_russia_with_love.rst
@@ -68,7 +68,7 @@ connections through Tor, so this'll break our ability to 
connect to Tor's
 control port. To use this approach simply replace the query() function above
 with...
 
-.. literalinclude::  /_static/example/client_usage_using_socksipy.py
+.. literalinclude:: /_static/example/client_usage_using_socksipy.py
:caption: `[Download] <../_static/example/client_usage_using_socksipy.py>`__
:language: python
 
diff --git a/stem/manual.py b/stem/manual.py
index dbde9827..e7658317 100644
--- a/stem/manual.py
+++ b/stem/manual.py
@@ -21,7 +21,7 @@ Manual information includes arguments, signals, and probably 
most usefully the
 torrc configuration options. For example, say we want a little script that told
 us what our torrc options do...
 
-.. literalinclude::  /_static/example/manual_config_options.py
+.. literalinclude:: /_static/example/manual_config_options.py
:language: python
 
 |
diff --git a/test/unit/examples.py b/test/unit/examples.py
index 094322e6..12ffb60c 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -7,6 +7,7 @@ import binascii
 import functools
 import io
 import os
+import re
 import sys
 import unittest
 
@@ -231,13 +232,13 @@ class TestExamples(unittest.TestCase):
 
 stem.descriptor.remote.SINGLETON_DOWNLOADER = None
 
-  def test_runs_everything(self):
+  def test_everything_is_tested(self):
 """
 Ensure we have tests for all our examples.
 """
 
 all_examples = set([os.path.basename(path)[:-3] for path in 
stem.util.system.files_with_suffix(EXAMPLE_DIR, '.py')])
-tested_examples = set([method[5:] for method in dir(self) if 
method.startswith('test_') and method != 'test_runs_everything'])
+tested_examples = set([method[5:] for method in dir(self) if 
method.startswith('test_') and not method.startswith('test_everything_')])
 
 extra = sorted(tested_examples.difference(all_examples))
 missing = 
sorted(all_examples.difference(tested_examples).difference(UNTESTED))
@@ -248,6 +249,36 @@ class TestExamples(unittest.TestCase):
 if missing:
   self.fail("Changed our examples directory? The following are untested: 
%s" % ', '.join(missing))
 
+  def test_everything_is_referenced(self):
+"""
+Ensure that all our examples are referenced our website. Otherwise they're
+dead code.
+"""
+
+all_examples = set([os.path.basename(path)[:-3] for path in 
stem.util.system.files_with_suffix(EXAMPLE_DIR, '.py')])
+
+include_regex = re.compile('.. literalinclude:: 
/_static/example/(\\S*).py')
+referenced_examples = set()
+
+for path in 
stem.util.system.files_with_suffix(os.path.join(test.STEM_BASE, 'docs'), 
'.rst'):
+  with open(path) as example_file:
+referenced_examples.update(include_regex.findall(example_file.read()))
+
+for path in 
stem.util.system.files_with_suffix(os.path.join(test.STEM_BASE, 'stem'), '.py'):
+  with open(path) as source_file:
+referenced_examples.update(include_regex.findall(source_file.read()))
+
+extra = sorted(referenced_examples.difference(all_examples))
+missing = sorted(all_examples.difference(referenced_examples))
+
+missing.remove('benchmark_stem')  # expanded copy of 
benchmark_server_descriptor_stem.py
+
+if extra:
+  self.fail("Changed our documentation? We reference the following 
examples which are not present: %s" % ', '.join(extra))
+
+if missing:
+  self.fail("Changed our documntation? The following examples are 
unreferenced: %s" % ', '.join(missing))
+
   @patch('stem.descriptor.remote.get_bandwidth_file')
   @patch('sys.stdout', new_callable = io.StringIO)
   def test_bandwidth_stats(self, stdout_mock, get_bandwidth_file_mock):



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move outdated_relays test

2020-10-02 Thread atagar
commit 9d328a42919f96bb43ac73ddf6e86736174d7d77
Author: Damian Johnson 
Date:   Sun Sep 27 14:13:29 2020 -0700

Move outdated_relays test
---
 test/unit/examples.py  | 23 +--
 test/unit/tutorial_examples.py | 23 ---
 2 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index efdac292..0fa140ab 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -134,6 +134,14 @@ Circuit 10 (GENERAL)
  +- 65242C91BFF30F165DA4D132C81A9EBA94B71D62 (torexit16, 176.67.169.171)
 """
 
+EXPECTED_OUTDATED_RELAYS = """\
+Checking for outdated relays...
+
+  0.1.0   Sambuddha Basu
+
+2 outdated relays found, 1 had contact information
+"""
+
 
 def _make_circ_event(circ_id, hop1, hop2, hop3):
   path = '$%s=%s,$%s=%s,$%s=%s' % (hop1[0], hop1[1], hop2[0], hop2[1], 
hop3[0], hop3[1])
@@ -423,8 +431,19 @@ class TestExamples(unittest.TestCase):
   def test_manual_config_options(self):
 pass
 
-  def test_outdated_relays(self):
-pass
+  @patch('stem.descriptor.remote.DescriptorDownloader')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_outdated_relays(self, stdout_mock, downloader_mock):
+downloader_mock().get_server_descriptors.return_value = [
+  RelayDescriptor.create({'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}),
+  RelayDescriptor.create({'platform': 'node-Tor 0.1.0 on Linux x86_64'}),
+  RelayDescriptor.create({'opt': 'contact Random Person ad...@gtr-10.de', 
'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}),
+  RelayDescriptor.create({'opt': 'contact Sambuddha Basu', 'platform': 
'node-Tor 0.1.0 on Linux x86_64'}),
+]
+
+import outdated_relays
+
+self.assertEqual(EXPECTED_OUTDATED_RELAYS, stdout_mock.getvalue())
 
   def test_persisting_a_consensus(self):
 pass
diff --git a/test/unit/tutorial_examples.py b/test/unit/tutorial_examples.py
index 4df9f6c4..0badb937 100644
--- a/test/unit/tutorial_examples.py
+++ b/test/unit/tutorial_examples.py
@@ -11,7 +11,6 @@ from unittest.mock import Mock, patch
 
 from stem.descriptor.networkstatus import NetworkStatusDocumentV3
 from stem.descriptor.router_status_entry import RouterStatusEntryV3
-from stem.descriptor.server_descriptor import RelayDescriptor
 from stem.directory import DIRECTORY_AUTHORITIES
 from stem.response import ControlMessage
 
@@ -25,14 +24,6 @@ PURPOSE=%s'
 
 PATH_CONTENT = '$%s=%s,$%s=%s,$%s=%s'
 
-OUTDATED_RELAYS_OUTPUT = """\
-Checking for outdated relays...
-
-  0.1.0   Sambuddha Basu
-
-2 outdated relays found, 1 had contact information
-"""
-
 COMPARE_FLAGS_OUTPUT = """\
 maatuska has the Running flag but moria1 doesn't: 
E2BB13AA2F6960CD93ABE5257A825687F3973C62
 moria1 has the Running flag but maatuska doesn't: 
546C54E2A89D88E0794D04AECBF1AC8AC9DA81DE
@@ -87,20 +78,6 @@ def _get_router_status(address = None, port = None, nickname 
= None, fingerprint
 
 
 class TestTutorialExamples(unittest.TestCase):
-  @patch('sys.stdout', new_callable = io.StringIO)
-  @patch('stem.descriptor.remote.DescriptorDownloader')
-  def test_outdated_relays(self, downloader_mock, stdout_mock):
-downloader_mock().get_server_descriptors.return_value = [
-  RelayDescriptor.create({'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}),
-  RelayDescriptor.create({'platform': 'node-Tor 0.1.0 on Linux x86_64'}),
-  RelayDescriptor.create({'opt': 'contact Random Person ad...@gtr-10.de', 
'platform': 'node-Tor 0.2.3.0 on Linux x86_64'}),
-  RelayDescriptor.create({'opt': 'contact Sambuddha Basu', 'platform': 
'node-Tor 0.1.0 on Linux x86_64'}),
-]
-
-exec_documentation_example('outdated_relays.py')
-
-self.assertCountEqual(OUTDATED_RELAYS_OUTPUT.splitlines(), 
stdout_mock.getvalue().splitlines())
-
   @patch('sys.stdout', new_callable = io.StringIO)
   @patch('stem.descriptor.remote.Query')
   @patch('stem.directory.Authority.from_cache')



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move descriptor_from_tor_data_directory test

2020-10-02 Thread atagar
commit 68b57bfe7a9615a642ae98c0bcdb20ddf8e5051b
Author: Damian Johnson 
Date:   Sun Sep 27 17:20:17 2020 -0700

Move descriptor_from_tor_data_directory test
---
 test/unit/examples.py | 12 ++--
 test/unit/tutorial.py | 20 
 2 files changed, 10 insertions(+), 22 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index ef1d9ed9..c972c7e9 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -420,8 +420,16 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual('found relay caerSidi 
(A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
 
-  def test_descriptor_from_tor_data_directory(self):
-pass
+  @patch('stem.descriptor.parse_file')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_descriptor_from_tor_data_directory(self, stdout_mock, 
parse_file_mock):
+parse_file_mock.return_value = [RouterStatusEntryV3.create({
+  'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 71.35.150.29 9001 0',
+})]
+
+import descriptor_from_tor_data_directory
+
+self.assertEqual('found relay caerSidi 
(A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
 
   def test_download_descriptor(self):
 pass
diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py
index d6b6ee3b..e2b621e8 100644
--- a/test/unit/tutorial.py
+++ b/test/unit/tutorial.py
@@ -9,8 +9,6 @@ import stem.descriptor.remote
 
 from unittest.mock import patch
 
-from stem.descriptor.router_status_entry import RouterStatusEntryV3
-from stem.descriptor.networkstatus import NetworkStatusDocumentV3
 from stem.descriptor.server_descriptor import RelayDescriptor
 
 MIRROR_MIRROR_OUTPUT = """\
@@ -27,24 +25,6 @@ class TestTutorial(unittest.TestCase):
 
 stem.descriptor.remote.SINGLETON_DOWNLOADER = None
 
-  @patch('sys.stdout', new_callable = io.StringIO)
-  @patch('%s.open' % __name__, create = True)
-  def test_mirror_mirror_on_the_wall_3(self, open_mock, stdout_mock):
-def tutorial_example():
-  from stem.descriptor import parse_file
-
-  for desc in parse_file(open('/home/atagar/.tor/cached-consensus')):
-print('found relay %s (%s)' % (desc.nickname, desc.fingerprint))
-
-test_file = io.BytesIO(NetworkStatusDocumentV3.content(routers = 
[RouterStatusEntryV3.create({
-  'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 71.35.150.29 9001 0',
-})]))
-test_file.name = '/home/atagar/.tor/cached-consensus'
-open_mock.return_value = test_file
-
-tutorial_example()
-self.assertEqual('found relay caerSidi 
(A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
-
   @patch('sys.stdout', new_callable = io.StringIO)
   @patch('stem.descriptor.remote.DescriptorDownloader')
   def test_mirror_mirror_on_the_wall_5(self, downloader_mock, stdout_mock):



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test custom_path_selection example

2020-10-02 Thread atagar
commit c01daf3be5be2906a4dfd0d85464dee9667d2d1a
Author: Damian Johnson 
Date:   Mon Sep 28 16:25:46 2020 -0700

Test custom_path_selection example
---
 docs/_static/example/custom_path_selection.py |  4 ++--
 test/unit/examples.py | 22 --
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/docs/_static/example/custom_path_selection.py 
b/docs/_static/example/custom_path_selection.py
index d63a2069..551f7b2f 100644
--- a/docs/_static/example/custom_path_selection.py
+++ b/docs/_static/example/custom_path_selection.py
@@ -1,4 +1,4 @@
-import StringIO
+import io
 import time
 
 import pycurl
@@ -20,7 +20,7 @@ def query(url):
   Uses pycurl to fetch a site using the proxy on the SOCKS_PORT.
   """
 
-  output = StringIO.StringIO()
+  output = io.StringIO()
 
   query = pycurl.Curl()
   query.setopt(pycurl.URL, url)
diff --git a/test/unit/examples.py b/test/unit/examples.py
index 1b85c297..aa1c25ce 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -427,8 +427,26 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual('found relay caerSidi 
(A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
 
-  def test_custom_path_selection(self):
-pass
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_custom_path_selection(self, stdout_mock, from_port_mock):
+original_modules = dict(sys.modules)
+
+try:
+  # pycurl mocked out so its query method returns an empty string
+
+  sys.modules['pycurl'] = Mock()
+
+  controller = from_port_mock().__enter__()
+  controller.get_network_statuses.return_value = 
[RouterStatusEntryV2.create({
+'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 71.35.150.29 9001 0',
+  })]
+
+  import custom_path_selection
+
+  self.assertEqual("A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB => Request 
didn't have the right content\n", stdout_mock.getvalue())
+finally:
+  sys.modules = original_modules
 
   def test_descriptor_from_orport(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test event_listening example

2020-10-02 Thread atagar
commit 4da373ca6994bf9954755ba5821fd4e39c507619
Author: Damian Johnson 
Date:   Tue Sep 29 14:05:17 2020 -0700

Test event_listening example
---
 docs/_static/example/event_listening.py | 42 -
 test/unit/examples.py   | 18 --
 2 files changed, 37 insertions(+), 23 deletions(-)

diff --git a/docs/_static/example/event_listening.py 
b/docs/_static/example/event_listening.py
index ff8c1469..b808a977 100644
--- a/docs/_static/example/event_listening.py
+++ b/docs/_static/example/event_listening.py
@@ -7,21 +7,21 @@ from stem.util import str_tools
 # colors that curses can handle
 
 COLOR_LIST = {
-  "red": curses.COLOR_RED,
-  "green": curses.COLOR_GREEN,
-  "yellow": curses.COLOR_YELLOW,
-  "blue": curses.COLOR_BLUE,
-  "cyan": curses.COLOR_CYAN,
-  "magenta": curses.COLOR_MAGENTA,
-  "black": curses.COLOR_BLACK,
-  "white": curses.COLOR_WHITE,
+  'red': curses.COLOR_RED,
+  'green': curses.COLOR_GREEN,
+  'yellow': curses.COLOR_YELLOW,
+  'blue': curses.COLOR_BLUE,
+  'cyan': curses.COLOR_CYAN,
+  'magenta': curses.COLOR_MAGENTA,
+  'black': curses.COLOR_BLACK,
+  'white': curses.COLOR_WHITE,
 }
 
 GRAPH_WIDTH = 40
 GRAPH_HEIGHT = 8
 
-DOWNLOAD_COLOR = "green"
-UPLOAD_COLOR = "blue"
+DOWNLOAD_COLOR = 'green'
+UPLOAD_COLOR = 'blue'
 
 def main():
   with Controller.from_port(port = 9051) as controller:
@@ -74,10 +74,10 @@ def _render_graph(window, bandwidth_rates):
 
   # show the latest values at the top
 
-  label = "Downloaded (%s/s):" % str_tools.size_label(download_rates[0], 1)
+  label = 'Downloaded (%s/s):' % str_tools.size_label(download_rates[0], 1)
   window.addstr(0, 1, label, DOWNLOAD_COLOR, curses.A_BOLD)
 
-  label = "Uploaded (%s/s):" % str_tools.size_label(upload_rates[0], 1)
+  label = 'Uploaded (%s/s):' % str_tools.size_label(upload_rates[0], 1)
   window.addstr(0, GRAPH_WIDTH + 7, label, UPLOAD_COLOR, curses.A_BOLD)
 
   # draw the graph bounds in KB
@@ -85,24 +85,24 @@ def _render_graph(window, bandwidth_rates):
   max_download_rate = max(download_rates)
   max_upload_rate = max(upload_rates)
 
-  window.addstr(1, 1, "%4i" % (max_download_rate / 1024), DOWNLOAD_COLOR)
-  window.addstr(GRAPH_HEIGHT, 1, "   0", DOWNLOAD_COLOR)
+  window.addstr(1, 1, '%4i' % (max_download_rate / 1024), DOWNLOAD_COLOR)
+  window.addstr(GRAPH_HEIGHT, 1, '   0', DOWNLOAD_COLOR)
 
-  window.addstr(1, GRAPH_WIDTH + 7, "%4i" % (max_upload_rate / 1024), 
UPLOAD_COLOR)
-  window.addstr(GRAPH_HEIGHT, GRAPH_WIDTH + 7, "   0", UPLOAD_COLOR)
+  window.addstr(1, GRAPH_WIDTH + 7, '%4i' % (max_upload_rate / 1024), 
UPLOAD_COLOR)
+  window.addstr(GRAPH_HEIGHT, GRAPH_WIDTH + 7, '   0', UPLOAD_COLOR)
 
   # draw the graph
 
   for col in range(GRAPH_WIDTH):
 col_height = GRAPH_HEIGHT * download_rates[col] / max(max_download_rate, 1)
 
-for row in range(col_height):
-  window.addstr(GRAPH_HEIGHT - row, col + 6, " ", DOWNLOAD_COLOR, 
curses.A_STANDOUT)
+for row in range(int(col_height)):
+  window.addstr(GRAPH_HEIGHT - row, col + 6, ' ', DOWNLOAD_COLOR, 
curses.A_STANDOUT)
 
 col_height = GRAPH_HEIGHT * upload_rates[col] / max(max_upload_rate, 1)
 
-for row in range(col_height):
-  window.addstr(GRAPH_HEIGHT - row, col + GRAPH_WIDTH + 12, " ", 
UPLOAD_COLOR, curses.A_STANDOUT)
+for row in range(int(col_height)):
+  window.addstr(GRAPH_HEIGHT - row, col + GRAPH_WIDTH + 12, ' ', 
UPLOAD_COLOR, curses.A_STANDOUT)
 
   window.refresh()
 
@@ -154,7 +154,7 @@ class Window(object):
 
 if color is not None:
   if color not in self._colors:
-recognized_colors = ", ".join(self._colors.keys())
+recognized_colors = ', '.join(self._colors.keys())
 raise ValueError("The '%s' color isn't recognized: %s" % (color, 
recognized_colors))
 
   attr |= self._colors[color]
diff --git a/test/unit/examples.py b/test/unit/examples.py
index 35aa80bb..d9a3f6fa 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -539,8 +539,22 @@ class TestExamples(unittest.TestCase):
 finally:
   sys.modules = original_modules
 
-  def test_event_listening(self):
-pass
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  def test_event_listening(self, from_port_mock):
+# This is a lengthy example that's mostly curses. This is just a surface
+# level test to check for syntax issues and such.
+
+original_modules = dict(sys.modules)
+
+try:
+  sys.modules['curses'] = Mock()
+
+  import event_listening
+
+  event_listening.main()
+  event_listening._render_graph(Mock(), [(0, 0)] * 
event_listening.GRAPH_WIDTH)
+finally:
+  sys.modules = original_modules
 
   @patch('stem.control.Controller.from_port', spec = Controller)
   @patch('sys.stdout', new_callable = io.StringIO)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move compare_flags test

2020-10-02 Thread atagar
commit ebdd4538f444cf8ee576d2a3969379c50179f7ca
Author: Damian Johnson 
Date:   Sun Sep 27 14:47:18 2020 -0700

Move compare_flags test
---
 docs/_static/example/compare_flags.py |  2 +-
 test/unit/examples.py | 44 +--
 test/unit/tutorial_examples.py| 49 ---
 3 files changed, 43 insertions(+), 52 deletions(-)

diff --git a/docs/_static/example/compare_flags.py 
b/docs/_static/example/compare_flags.py
index 1efb1d2c..94c236e6 100644
--- a/docs/_static/example/compare_flags.py
+++ b/docs/_static/example/compare_flags.py
@@ -35,7 +35,7 @@ for vote in votes.values():
 
 # Finally, compare moria1's votes to maatuska's votes.
 
-for fingerprint in all_fingerprints:
+for fingerprint in sorted(all_fingerprints):
   moria1_vote = votes['moria1'].routers.get(fingerprint)
   maatuska_vote = votes['maatuska'].routers.get(fingerprint)
 
diff --git a/test/unit/examples.py b/test/unit/examples.py
index 0fa140ab..8fca999a 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -18,8 +18,10 @@ import test.require
 from stem.control import Controller
 from stem.descriptor.bandwidth_file import BandwidthFile
 from stem.descriptor.extrainfo_descriptor import RelayExtraInfoDescriptor
+from stem.descriptor.networkstatus import NetworkStatusDocumentV3
 from stem.descriptor.router_status_entry import RouterStatusEntryV3
 from stem.descriptor.server_descriptor import RelayDescriptor
+from stem.directory import DIRECTORY_AUTHORITIES
 from stem.exit_policy import ExitPolicy
 from stem.response import ControlMessage
 from unittest.mock import Mock, patch
@@ -105,6 +107,14 @@ EXPECTED_COLLECTOR_READING = """\
   caerSidi (4F0C867DF0EF68160568C826838F482CEA7CFE44)
 """
 
+EXPECTED_COMPARE_FLAGS = """\
+moria1 has the Running flag but maatuska doesn't: 
546C54E2A89D88E0794D04AECBF1AC8AC9DA81DE
+maatuska has the Running flag but moria1 doesn't: 
6871F682350BA931838C0EC1E4A23044DAE06A73
+maatuska has the Running flag but moria1 doesn't: 
92FCB6748A40E6088E22FBAB943AB2DD743EA818
+moria1 has the Running flag but maatuska doesn't: 
DCAEC3D069DC39AAE43D13C8AF31B5645E05ED61
+maatuska has the Running flag but moria1 doesn't: 
E2BB13AA2F6960CD93ABE5257A825687F3973C62
+"""
+
 EXPECTED_EXIT_USED = """\
 Tracking requests for tor exits. Press 'enter' to end.
 
@@ -321,8 +331,38 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual(EXPECTED_COLLECTOR_READING, stdout_mock.getvalue())
 
-  def test_compare_flags(self):
-pass
+  @patch('stem.directory.Authority.from_cache')
+  @patch('stem.descriptor.remote.Query')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_compare_flags(self, stdout_mock, query_mock, authorities_mock):
+authorities_mock().items.return_value = [
+  ('moria1', DIRECTORY_AUTHORITIES['moria1']),
+  ('maatuska', DIRECTORY_AUTHORITIES['maatuska']),
+]
+
+r_line = 'caerSidi %s oQZFLYe9e4A7bOkWKR7TaNxb0JE 2012-08-06 11:19:31 
71.35.150.29 9001 0'
+
+moria1_consensus = NetworkStatusDocumentV3.create(routers = [
+  RouterStatusEntryV3.create({'r': r_line % 
'kvy2dIpA5giOIvurlDqy3XQ+qBg=', 's': ' '}),
+  RouterStatusEntryV3.create({'r': r_line % 
'aHH2gjULqTGDjA7B5KIwRNrganM=', 's': ' '}),
+  RouterStatusEntryV3.create({'r': r_line % 
'4rsTqi9pYM2Tq+UleoJWh/OXPGI=', 's': ' '}),
+  RouterStatusEntryV3.create({'r': r_line % 
'VGxU4qidiOB5TQSuy/Gsisnagd4='}),
+  RouterStatusEntryV3.create({'r': r_line % 
'3K7D0GncOarkPRPIrzG1ZF4F7WE='}),
+])
+
+maatuska_consensus = NetworkStatusDocumentV3.create(routers = [
+  RouterStatusEntryV3.create({'r': r_line % 
'kvy2dIpA5giOIvurlDqy3XQ+qBg='}),
+  RouterStatusEntryV3.create({'r': r_line % 
'aHH2gjULqTGDjA7B5KIwRNrganM='}),
+  RouterStatusEntryV3.create({'r': r_line % 
'4rsTqi9pYM2Tq+UleoJWh/OXPGI='}),
+  RouterStatusEntryV3.create({'r': r_line % 
'VGxU4qidiOB5TQSuy/Gsisnagd4=', 's': ' '}),
+  RouterStatusEntryV3.create({'r': r_line % 
'3K7D0GncOarkPRPIrzG1ZF4F7WE=', 's': ' '}),
+])
+
+query_mock().run.side_effect = [[moria1_consensus], [maatuska_consensus]]
+
+import compare_flags
+
+self.assertEqual(EXPECTED_COMPARE_FLAGS, stdout_mock.getvalue())
 
   def test_create_descriptor(self):
 pass
diff --git a/test/unit/tutorial_examples.py b/test/unit/tutorial_examples.py
index 0badb937..ad9a68f4 100644
--- a/test/unit/tutorial_examples.py
+++ b/test/unit/tutorial_examples.py
@@ -24,14 +24,6 @@ PURPOSE=%s'
 
 PATH_CONTENT = '$%s=%s,$%s=%s,$%s=%s'
 
-COMPARE_FLAGS_OUTPUT = """\
-maatuska has the Running flag but moria1 doesn't: 
E2BB13AA2F6960CD93ABE5257A825687F3973C62
-moria1 has the Running flag but maatuska doesn't: 
546C54E2A89D88E0794D04AECBF1AC8AC9DA81DE
-maatuska has the Running flag but moria1 doesn't: 
92FCB6748A40E6088E22FBAB943AB2DD743EA818
-maatuska has the Running flag but moria1 doesn't: 
6871F682350BA931838C0EC1E4A23044DAE06A73
-moria1 has the Running flag but maatuska 

[tor-commits] [stem/master] Test download_descriptor example

2020-10-02 Thread atagar
commit c8b543368352a013c17cfe41baf6e370ee475826
Author: Damian Johnson 
Date:   Mon Sep 28 17:18:37 2020 -0700

Test download_descriptor example
---
 docs/_static/example/download_descriptor.py | 12 +---
 test/unit/examples.py   | 30 -
 2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/docs/_static/example/download_descriptor.py 
b/docs/_static/example/download_descriptor.py
index 7e712ecf..89ea4a6c 100644
--- a/docs/_static/example/download_descriptor.py
+++ b/docs/_static/example/download_descriptor.py
@@ -57,9 +57,6 @@ def parse(argv):
 
   for opt, arg in recognized_args:
 if opt in ('-t', '--type'):
-  if arg not in VALID_TYPES:
-raise ValueError("'%s' isn't a recognized decriptor type, options are: 
%s" % (arg, ', '.join(VALID_TYPES)))
-
   args['descriptor_type'] = arg
 elif opt in ('-f', '--fingerprint'):
   if not stem.util.tor_tools.is_valid_fingerprint(arg):
@@ -88,9 +85,9 @@ def parse(argv):
   return Args(**args)
 
 
-def main():
+def main(argv):
   try:
-args = parse(sys.argv[1:])
+args = parse(argv)
   except ValueError as exc:
 print(exc)
 sys.exit(1)
@@ -125,7 +122,8 @@ def main():
 print("'%s' is not a recognized descriptor type, options are: %s" % 
(args.descriptor_type, ', '.join(VALID_TYPES)))
 sys.exit(1)
 
-  print(desc)
+  if desc:
+print(desc)
 
 if __name__ == '__main__':
-  main()
+  main(sys.argv[1:])
diff --git a/test/unit/examples.py b/test/unit/examples.py
index af049f57..eb9bdb2a 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -115,6 +115,18 @@ moria1 has the Running flag but maatuska doesn't: 
DCAEC3D069DC39AAE43D13C8AF31B5
 maatuska has the Running flag but moria1 doesn't: 
E2BB13AA2F6960CD93ABE5257A825687F3973C62
 """
 
+EXPECTED_DOWNLOAD_DESCRIPTOR_UNKNOWN_TYPE = """\
+Downloading kaboom descriptor from 128.31.0.34:9131...
+
+'kaboom' is not a recognized descriptor type, options are: server, extrainfo, 
consensus
+"""
+
+EXPECTED_DOWNLOAD_DESCRIPTOR_PREFIX = """\
+Downloading server descriptor from 1.2.3.4:443...
+
+router caerSidi 71.35.133.197 9001 0 0
+"""
+
 EXPECTED_EXIT_USED = """\
 Tracking requests for tor exits. Press 'enter' to end.
 
@@ -484,8 +496,24 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual('found relay caerSidi 
(A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
 
+  @patch('sys.exit', Mock())
   def test_download_descriptor(self):
-pass
+import download_descriptor
+
+with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
+  download_descriptor.main(['--help'])
+  self.assertTrue(stdout_mock.getvalue().startswith("Downloads a 
descriptor through Tor's ORPort"))
+
+with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
+  download_descriptor.main(['--type', 'kaboom'])
+  self.assertEqual(EXPECTED_DOWNLOAD_DESCRIPTOR_UNKNOWN_TYPE, 
stdout_mock.getvalue())
+
+server_desc = RelayDescriptor.create({'router': 'caerSidi 71.35.133.197 
9001 0 0'})
+
+with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
+  with patch('stem.descriptor.remote.get_server_descriptors', 
_download_of(server_desc)):
+download_descriptor.main(['--dirport', '1.2.3.4:443'])
+
self.assertTrue(stdout_mock.getvalue().startswith(EXPECTED_DOWNLOAD_DESCRIPTOR_PREFIX))
 
   def test_ephemeral_hidden_services(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test slow_listener example

2020-10-02 Thread atagar
commit 2880be78fd34fd48939ddb417d2c4b7d725e57f6
Author: Damian Johnson 
Date:   Fri Oct 2 13:23:46 2020 -0700

Test slow_listener example
---
 test/unit/examples.py | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 73bae36c..5e2bbc78 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -930,8 +930,25 @@ class TestExamples(unittest.TestCase):
 if os.path.exists('/tmp/descriptor_dump'):
   os.remove('/tmp/descriptor_dump')
 
-  def test_slow_listener(self):
-pass
+  @patch('time.sleep')
+  @patch('time.time', Mock(return_value = 123))
+  @patch('stem.control.Controller.authenticate', Mock())
+  @patch('stem.control.Controller.is_alive', Mock(return_value = True))
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_slow_listener(self, stdout_mock, from_port_mock, sleep_mock):
+controller = Controller(stem.socket.ControlSocket())
+from_port_mock.return_value = controller
+
+# emits a BW event when the example runs time.sleep() at the end, but *not*
+# within the listener
+
+bw_event = ControlMessage.from_str('650 BW 15 25', 'EVENT', normalize = 
True)
+sleep_mock.side_effect = lambda duration: 
controller._handle_event(bw_event) if duration == 10 else None
+
+import slow_listener
+
+self.assertEqual("processing a BW event that's 0.0 seconds old (0 more 
events are waiting)\n", stdout_mock.getvalue())
 
   @patch('stem.descriptor.remote.DescriptorDownloader')
   @patch('sys.stdout', new_callable = io.StringIO)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move descriptor_from_tor_control_socket test

2020-10-02 Thread atagar
commit 21725bd2f4efcb16f5300b2a9370a8817226a0d3
Author: Damian Johnson 
Date:   Sun Sep 27 16:11:42 2020 -0700

Move descriptor_from_tor_control_socket test
---
 test/unit/examples.py | 13 +++--
 test/unit/tutorial.py | 13 +
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index a117bb24..5b56261e 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -400,8 +400,17 @@ class TestExamples(unittest.TestCase):
   def test_descriptor_from_orport(self):
 pass
 
-  def test_descriptor_from_tor_control_socket(self):
-pass
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_descriptor_from_tor_control_socket(self, stdout_mock, 
from_port_mock):
+controller = from_port_mock().__enter__()
+controller.get_network_statuses.return_value = 
[RouterStatusEntryV2.create({
+  'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 71.35.150.29 9001 0',
+})]
+
+import descriptor_from_tor_control_socket
+
+self.assertEqual('found relay caerSidi 
(A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
 
   def test_descriptor_from_tor_data_directory(self):
 pass
diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py
index 90dfc661..d1093bd5 100644
--- a/test/unit/tutorial.py
+++ b/test/unit/tutorial.py
@@ -12,7 +12,7 @@ import test
 from unittest.mock import Mock, patch
 
 from stem.control import Controller
-from stem.descriptor.router_status_entry import RouterStatusEntryV2, 
RouterStatusEntryV3
+from stem.descriptor.router_status_entry import RouterStatusEntryV3
 from stem.descriptor.networkstatus import NetworkStatusDocumentV3
 from stem.descriptor.server_descriptor import RelayDescriptor
 from stem.exit_policy import ExitPolicy
@@ -112,17 +112,6 @@ class TestTutorial(unittest.TestCase):
 
 self.assertEqual(OVER_THE_RIVER_OUTPUT, stdout_mock.getvalue())
 
-  @patch('sys.stdout', new_callable = io.StringIO)
-  @patch('stem.control.Controller.from_port', spec = Controller)
-  def test_mirror_mirror_on_the_wall_2(self, from_port_mock, stdout_mock):
-controller = from_port_mock().__enter__()
-controller.get_network_statuses.return_value = 
[RouterStatusEntryV2.create({
-  'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 71.35.150.29 9001 0',
-})]
-
-exec_documentation_example('descriptor_from_tor_control_socket.py')
-self.assertEqual('found relay caerSidi 
(A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
-
   @patch('sys.stdout', new_callable = io.StringIO)
   @patch('%s.open' % __name__, create = True)
   def test_mirror_mirror_on_the_wall_3(self, open_mock, stdout_mock):



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move hello_world test

2020-10-02 Thread atagar
commit 21ce92eda4855e8091b163713e8f8ed00b4181ef
Author: Damian Johnson 
Date:   Sun Sep 27 16:06:45 2020 -0700

Move hello_world test
---
 test/unit/examples.py | 14 --
 test/unit/tutorial.py | 12 
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 3f528b80..9250280e 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -438,8 +438,18 @@ class TestExamples(unittest.TestCase):
   def test_get_hidden_service_descriptor(self):
 pass
 
-  def test_hello_world(self):
-pass
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_hello_world(self, stdout_mock, from_port_mock):
+controller = from_port_mock().__enter__()
+controller.get_info.side_effect = lambda arg: {
+  'traffic/read': '33406',
+  'traffic/written': '29649',
+}[arg]
+
+import hello_world
+
+self.assertEqual('My Tor relay has read 33406 bytes and written 29649.\n', 
stdout_mock.getvalue())
 
   def test_introduction_points(self):
 pass
diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py
index 140bbba5..92793afe 100644
--- a/test/unit/tutorial.py
+++ b/test/unit/tutorial.py
@@ -46,18 +46,6 @@ class TestTutorial(unittest.TestCase):
 
 stem.descriptor.remote.SINGLETON_DOWNLOADER = None
 
-  @patch('sys.stdout', new_callable = io.StringIO)
-  @patch('stem.control.Controller.from_port', spec = Controller)
-  def test_the_little_relay_that_could(self, from_port_mock, stdout_mock):
-controller = from_port_mock().__enter__()
-controller.get_info.side_effect = lambda arg: {
-  'traffic/read': '33406',
-  'traffic/written': '29649',
-}[arg]
-
-exec_documentation_example('hello_world.py')
-self.assertEqual('My Tor relay has read 33406 bytes and written 29649.\n', 
stdout_mock.getvalue())
-
   @patch('sys.stdout', new_callable = io.StringIO)
   @patch('shutil.rmtree')
   @patch('stem.control.Controller.from_port', spec = Controller)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Drop duplicate collector_reading test

2020-10-02 Thread atagar
commit 05b005515e70f230b48851b0efa8fad58af95953
Author: Damian Johnson 
Date:   Sun Sep 27 16:14:12 2020 -0700

Drop duplicate collector_reading test

I wrote another test for collector_reading before realizing we already had
coverage for several examples. Despite being years apart they amusingly were
almost identical.
---
 test/unit/examples.py |  2 +-
 test/unit/tutorial.py | 11 ---
 2 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 5b56261e..cadf3048 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -330,7 +330,7 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual(EXPECTED_COLLECTOR_CACHING, stdout_mock.getvalue())
 
-  @patch('stem.descriptor.collector.CollecTor.get_server_descriptors')
+  @patch('stem.descriptor.collector.get_server_descriptors')
   @patch('sys.stdout', new_callable = io.StringIO)
   def test_collector_reading(self, stdout_mock, server_desc_mock):
 server_desc_mock.return_value = [
diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py
index d1093bd5..472285ad 100644
--- a/test/unit/tutorial.py
+++ b/test/unit/tutorial.py
@@ -130,17 +130,6 @@ class TestTutorial(unittest.TestCase):
 tutorial_example()
 self.assertEqual('found relay caerSidi 
(A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
 
-  @patch('sys.stdout', new_callable = io.StringIO)
-  @patch('stem.descriptor.collector.get_server_descriptors')
-  def test_mirror_mirror_on_the_wall_4(self, get_desc_mock, stdout_mock):
-get_desc_mock.return_value = iter([RelayDescriptor.create({
-  'router': 'caerSidi 71.35.133.197 9001 0 0',
-  'fingerprint': '2C3C 4662 5698 B6D6 7DF3 2BC1 918A D3EE 1F99 06B1',
-}, exit_policy = ExitPolicy('accept *:*'), validate = False)])
-
-exec_documentation_example('collector_reading.py')
-self.assertEqual('1 relays published an exiting policy today...\n\n  
caerSidi (2C3C46625698B6D67DF32BC1918AD3EE1F9906B1)\n', stdout_mock.getvalue())
-
   @patch('sys.stdout', new_callable = io.StringIO)
   @patch('stem.descriptor.remote.DescriptorDownloader')
   def test_mirror_mirror_on_the_wall_5(self, downloader_mock, stdout_mock):



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test introduction_points example

2020-10-02 Thread atagar
commit 9f12b49dba84bc4232b0ea03842a4e8e2142a880
Author: Damian Johnson 
Date:   Tue Sep 29 15:09:38 2020 -0700

Test introduction_points example
---
 test/unit/examples.py | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index df46a30c..b6eb8016 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -145,6 +145,14 @@ Exit relay for our connection to 64.15.112.44:80
 
 """
 
+EXPECTED_INTRODUCTION_POINTS = """\
+DuckDuckGo's introduction points are...
+
+  178.62.222.129:443 => iwki77xtbvp6qvedfrwdzncxs3ckayeu
+  46.4.174.52:443 => em4gjk6eiiualhmlyiifrzc7lbtrsbip
+  62.210.82.169:443 => jqhfl364x3upe6lqnxizolewlfrsw2zy
+"""
+
 EXPECTED_LIST_CIRCUITS = """\
 
 Circuit 4 (GENERAL)
@@ -621,8 +629,15 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual('My Tor relay has read 33406 bytes and written 29649.\n', 
stdout_mock.getvalue())
 
-  def test_introduction_points(self):
-pass
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_introduction_points(self, stdout_mock, from_port_mock):
+controller = from_port_mock().__enter__()
+controller.get_hidden_service_descriptor.return_value = 
next(stem.descriptor.parse_file(os.path.join(DESC_DIR, 
'hidden_service_duckduckgo')))
+
+import introduction_points
+
+self.assertEqual(EXPECTED_INTRODUCTION_POINTS, stdout_mock.getvalue())
 
   @patch('stem.control.Controller.from_port', spec = Controller)
   @patch('sys.stdout', new_callable = io.StringIO)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move votes_by_bandwidth_authorities test

2020-10-02 Thread atagar
commit 2719fd3c44e8623f07094687146839aed0285e63
Author: Damian Johnson 
Date:   Sun Sep 27 14:55:07 2020 -0700

Move votes_by_bandwidth_authorities test
---
 test/unit/examples.py  | 41 --
 test/unit/tutorial_examples.py | 45 +-
 2 files changed, 40 insertions(+), 46 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 8fca999a..1b055628 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -152,6 +152,15 @@ Checking for outdated relays...
 2 outdated relays found, 1 had contact information
 """
 
+EXPECTED_VOTES_BY_BANDWIDTH_AUTHORITIES = """\
+Getting gabelmoo's vote from 
http://131.188.40.189:80/tor/status-vote/current/authority:
+  5935 measured entries and 1332 unmeasured
+Getting moria1's vote from 
http://128.31.0.39:9131/tor/status-vote/current/authority:
+  6647 measured entries and 625 unmeasured
+Getting maatuska's vote from 
http://171.25.193.9:443/tor/status-vote/current/authority:
+  6313 measured entries and 1112 unmeasured
+"""
+
 
 def _make_circ_event(circ_id, hop1, hop2, hop3):
   path = '$%s=%s,$%s=%s,$%s=%s' % (hop1[0], hop1[1], hop2[0], hop2[1], 
hop3[0], hop3[1])
@@ -524,8 +533,36 @@ class TestExamples(unittest.TestCase):
   def test_validate_descriptor_content(self):
 pass
 
-  def test_votes_by_bandwidth_authorities(self):
-pass
+  @patch('stem.descriptor.remote.DescriptorDownloader.query')
+  @patch('stem.directory.Authority.from_cache')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_votes_by_bandwidth_authorities(self, stdout_mock, authorities_mock, 
query_mock):
+authorities_mock().values.return_value = [
+  DIRECTORY_AUTHORITIES['gabelmoo'],
+  DIRECTORY_AUTHORITIES['moria1'],
+  DIRECTORY_AUTHORITIES['maatuska'],
+]
+
+entry_with_measurement = RouterStatusEntryV3.create({'w': 'Bandwidth=1 
Measured=1'})
+entry_without_measurement = RouterStatusEntryV3.create()
+
+query1 = Mock()
+query1.download_url = 
'http://131.188.40.189:80/tor/status-vote/current/authority'
+query1.run.return_value = [entry_with_measurement] * 5935 + 
[entry_without_measurement] * 1332
+
+query2 = Mock()
+query2.download_url = 
'http://128.31.0.39:9131/tor/status-vote/current/authority'
+query2.run.return_value = [entry_with_measurement] * 6647 + 
[entry_without_measurement] * 625
+
+query3 = Mock()
+query3.download_url = 
'http://171.25.193.9:443/tor/status-vote/current/authority'
+query3.run.return_value = [entry_with_measurement] * 6313 + 
[entry_without_measurement] * 1112
+
+query_mock.side_effect = [query1, query2, query3]
+
+import votes_by_bandwidth_authorities
+
+self.assertEqual(EXPECTED_VOTES_BY_BANDWIDTH_AUTHORITIES, 
stdout_mock.getvalue())
 
   def test_words_with(self):
 pass
diff --git a/test/unit/tutorial_examples.py b/test/unit/tutorial_examples.py
index ad9a68f4..451bb2aa 100644
--- a/test/unit/tutorial_examples.py
+++ b/test/unit/tutorial_examples.py
@@ -7,11 +7,10 @@ import itertools
 import os
 import unittest
 
-from unittest.mock import Mock, patch
+from unittest.mock import patch
 
 from stem.descriptor.networkstatus import NetworkStatusDocumentV3
 from stem.descriptor.router_status_entry import RouterStatusEntryV3
-from stem.directory import DIRECTORY_AUTHORITIES
 from stem.response import ControlMessage
 
 from test.unit import exec_documentation_example
@@ -24,15 +23,6 @@ PURPOSE=%s'
 
 PATH_CONTENT = '$%s=%s,$%s=%s,$%s=%s'
 
-VOTES_BY_BANDWIDTH_AUTHORITIES_OUTPUT = """\
-Getting gabelmoo's vote from 
http://131.188.40.189:80/tor/status-vote/current/authority:
-  5935 measured entries and 1332 unmeasured
-Getting moria1's vote from 
http://128.31.0.39:9131/tor/status-vote/current/authority:
-  6647 measured entries and 625 unmeasured
-Getting maatuska's vote from 
http://171.25.193.9:443/tor/status-vote/current/authority:
-  6313 measured entries and 1112 unmeasured
-"""
-
 PERSISTING_A_CONSENSUS_OUTPUT = """\
 A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB: caerSidi
 """
@@ -70,39 +60,6 @@ def _get_router_status(address = None, port = None, nickname 
= None, fingerprint
 
 
 class TestTutorialExamples(unittest.TestCase):
-  @patch('sys.stdout', new_callable = io.StringIO)
-  @patch('stem.directory.Authority.from_cache')
-  @patch('stem.descriptor.remote.DescriptorDownloader.query')
-  def test_votes_by_bandwidth_authorities(self, query_mock, authorities_mock, 
stdout_mock):
-directory_values = [
-  DIRECTORY_AUTHORITIES['gabelmoo'],
-  DIRECTORY_AUTHORITIES['moria1'],
-  DIRECTORY_AUTHORITIES['maatuska'],
-]
-
-directory_values[0].address = '131.188.40.189'
-authorities_mock().values.return_value = directory_values
-
-entry_with_measurement = RouterStatusEntryV3.create({'w': 'Bandwidth=1 
Measured=1'})
-entry_without_measurement = RouterStatusEntryV3.create()
-
-query1 = Mock()
-query1.download_url = 

[tor-commits] [stem/master] Drop unused load_test example

2020-10-02 Thread atagar
commit 26d6f781bf97872645067096d272949dcfd4c3d9
Author: Damian Johnson 
Date:   Tue Sep 29 15:12:52 2020 -0700

Drop unused load_test example

Odd, commit 843facd added this example but didn't link to it within our
website. Rather than fix the trivial print() bug and test it simply 
removing.
---
 docs/_static/example/load_test.py | 25 -
 test/unit/examples.py |  3 ---
 2 files changed, 28 deletions(-)

diff --git a/docs/_static/example/load_test.py 
b/docs/_static/example/load_test.py
deleted file mode 100644
index e98e4c00..
--- a/docs/_static/example/load_test.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import os
-import time
-
-import stem.control
-import stem.util.proc
-import stem.util.str_tools
-
-start_time = time.time()
-samplings = []
-last_sample = None
-
-with stem.control.Controller.from_port() as controller:
-  controller.authenticate()
-  controller.add_event_listener(lambda *args: None, 'DEBUG')
-
-  while True:
-utime, stime = stem.util.proc.stats(os.getpid(), 
stem.util.proc.Stat.CPU_UTIME, stem.util.proc.Stat.CPU_STIME)
-total_cpu_time = float(utime) + float(stime)
-
-if last_sample:
-  samplings.append(total_cpu_time - last_sample)
-  print '%0.1f%% (%s)' % (sum(samplings) / len(samplings) * 100, 
stem.util.str_tools.time_label(time.time() - start_time))
-
-last_sample = total_cpu_time
-time.sleep(1)
diff --git a/test/unit/examples.py b/test/unit/examples.py
index b6eb8016..094322e6 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -673,9 +673,6 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual(EXPECTED_LIST_CIRCUITS, stdout_mock.getvalue())
 
-  def test_load_test(self):
-pass
-
   def test_manual_config_options(self):
 pass
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move current_descriptors test

2020-10-02 Thread atagar
commit b2cf76cb0cc69e16dfd34eec618262e4ac227f15
Author: Damian Johnson 
Date:   Sun Sep 27 16:08:49 2020 -0700

Move current_descriptors test
---
 test/unit/examples.py | 14 +++---
 test/unit/tutorial.py | 10 --
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 9250280e..a117bb24 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -19,7 +19,7 @@ from stem.control import Controller
 from stem.descriptor.bandwidth_file import BandwidthFile
 from stem.descriptor.extrainfo_descriptor import RelayExtraInfoDescriptor
 from stem.descriptor.networkstatus import NetworkStatusDocumentV3
-from stem.descriptor.router_status_entry import RouterStatusEntryV3
+from stem.descriptor.router_status_entry import RouterStatusEntryV2, 
RouterStatusEntryV3
 from stem.descriptor.server_descriptor import RelayDescriptor
 from stem.directory import DIRECTORY_AUTHORITIES
 from stem.exit_policy import ExitPolicy
@@ -383,8 +383,16 @@ class TestExamples(unittest.TestCase):
   def test_create_descriptor_content(self):
 pass
 
-  def test_current_descriptors(self):
-pass
+  @patch('stem.descriptor.remote.DescriptorDownloader')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_current_descriptors(self, stdout_mock, downloader_mock):
+downloader_mock().get_consensus.return_value = 
[RouterStatusEntryV2.create({
+  'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 71.35.150.29 9001 0',
+})]
+
+import current_descriptors
+
+self.assertEqual('found relay caerSidi 
(A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
 
   def test_custom_path_selection(self):
 pass
diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py
index 92793afe..90dfc661 100644
--- a/test/unit/tutorial.py
+++ b/test/unit/tutorial.py
@@ -112,16 +112,6 @@ class TestTutorial(unittest.TestCase):
 
 self.assertEqual(OVER_THE_RIVER_OUTPUT, stdout_mock.getvalue())
 
-  @patch('sys.stdout', new_callable = io.StringIO)
-  @patch('stem.descriptor.remote.DescriptorDownloader')
-  def test_mirror_mirror_on_the_wall_1(self, downloader_mock, stdout_mock):
-downloader_mock().get_consensus.return_value = 
[RouterStatusEntryV2.create({
-  'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 71.35.150.29 9001 0',
-})]
-
-exec_documentation_example('current_descriptors.py')
-self.assertEqual('found relay caerSidi 
(A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
-
   @patch('sys.stdout', new_callable = io.StringIO)
   @patch('stem.control.Controller.from_port', spec = Controller)
   def test_mirror_mirror_on_the_wall_2(self, from_port_mock, stdout_mock):



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test descriptor_from_orport example

2020-10-02 Thread atagar
commit 02ac67ca0b46ec1dcff0c5b0e9dcf4712a4fc238
Author: Damian Johnson 
Date:   Mon Sep 28 16:32:14 2020 -0700

Test descriptor_from_orport example
---
 test/unit/examples.py | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index aa1c25ce..af049f57 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -448,8 +448,18 @@ class TestExamples(unittest.TestCase):
 finally:
   sys.modules = original_modules
 
-  def test_descriptor_from_orport(self):
-pass
+  @patch('stem.descriptor.remote.DescriptorDownloader')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_descriptor_from_orport(self, stdout_mock, downloader_mock):
+downloader_mock().get_consensus.return_value = [
+  RouterStatusEntryV3.create({
+'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 71.35.150.29 9001 0',
+  })
+]
+
+import descriptor_from_orport
+
+self.assertEqual('found relay caerSidi 
(A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n', stdout_mock.getvalue())
 
   @patch('stem.control.Controller.from_port', spec = Controller)
   @patch('sys.stdout', new_callable = io.StringIO)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test queue_listener example

2020-10-02 Thread atagar
commit 437ea486834ae9e320675ec0c80aa4ecf293fcc6
Author: Damian Johnson 
Date:   Tue Sep 29 18:39:46 2020 -0700

Test queue_listener example
---
 test/unit/examples.py | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 0b4d7082..6e32a0f2 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -772,8 +772,18 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual(EXPECTED_PERSISTING_A_CONSENSUS, stdout_mock.getvalue())
 
-  def test_queue_listener(self):
-pass
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_queue_listener(self, stdout_mock, from_port_mock):
+bw_event = ControlMessage.from_str('650 BW 15 25', 'EVENT', normalize = 
True)
+
+controller = from_port_mock().__enter__()
+controller.add_event_listener.side_effect = lambda handler, event_type: 
handler(bw_event)
+
+with patch('time.time', Mock(side_effect = [1, 1, 10])):
+  import queue_listener
+
+self.assertEqual('I got a BW event for 15 bytes downloaded and 25 bytes 
uploaded\n', stdout_mock.getvalue())
 
   def test_read_with_parse_file(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move persisting_a_consensus tests

2020-10-02 Thread atagar
commit 1a8cff380c76b8a90a868472f92951cd08e35919
Author: Damian Johnson 
Date:   Sun Sep 27 15:58:27 2020 -0700

Move persisting_a_consensus tests
---
 test/settings.cfg  |  1 -
 test/unit/__init__.py  | 11 -
 test/unit/examples.py  | 54 +++--
 test/unit/tutorial.py  | 12 +-
 test/unit/tutorial_examples.py | 92 --
 5 files changed, 51 insertions(+), 119 deletions(-)

diff --git a/test/settings.cfg b/test/settings.cfg
index 26561327..91f287cf 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -290,7 +290,6 @@ test.unit_tests
 |test.unit.directory.authority.TestAuthority
 |test.unit.directory.fallback.TestFallback
 |test.unit.tutorial.TestTutorial
-|test.unit.tutorial_examples.TestTutorialExamples
 |test.unit.response.add_onion.TestAddOnionResponse
 |test.unit.response.control_message.TestControlMessage
 |test.unit.response.control_line.TestControlLine
diff --git a/test/unit/__init__.py b/test/unit/__init__.py
index 1b16bc99..7fb58a67 100644
--- a/test/unit/__init__.py
+++ b/test/unit/__init__.py
@@ -2,9 +2,6 @@
 Unit tests for the stem library.
 """
 
-import os
-import test
-
 __all__ = [
   'client',
   'connection',
@@ -16,11 +13,3 @@ __all__ = [
   'util',
   'version',
 ]
-
-
-def exec_documentation_example(filename):
-  path = os.path.join(test.STEM_BASE, 'docs', '_static', 'example', filename)
-
-  with open(path) as f:
-code = compile(f.read(), path, 'exec')
-exec(code)
diff --git a/test/unit/examples.py b/test/unit/examples.py
index 1b055628..3f528b80 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -152,6 +152,9 @@ Checking for outdated relays...
 2 outdated relays found, 1 had contact information
 """
 
+EXPECTED_PERSISTING_A_CONSENSUS = """\
+A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB: caerSidi
+"""
 EXPECTED_VOTES_BY_BANDWIDTH_AUTHORITIES = """\
 Getting gabelmoo's vote from 
http://131.188.40.189:80/tor/status-vote/current/authority:
   5935 measured entries and 1332 unmeasured
@@ -168,6 +171,12 @@ def _make_circ_event(circ_id, hop1, hop2, hop3):
   return ControlMessage.from_str(content, 'EVENT', normalize = True)
 
 
+def _download_of(desc):
+  query = Mock()
+  query.run.return_value = [desc]
+  return Mock(return_value = query)
+
+
 class TestExamples(unittest.TestCase):
   def setUp(self):
 self.original_path = list(sys.path)
@@ -268,11 +277,6 @@ class TestExamples(unittest.TestCase):
 
   @test.require.cryptography
   def test_check_digests(self):
-def download_of(desc):
-  query = Mock()
-  query.run.return_value = [desc]
-  return Mock(return_value = query)
-
 import check_digests as module
 fingerprint = 'A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB'
 
@@ -289,18 +293,18 @@ class TestExamples(unittest.TestCase):
   'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 71.35.150.29 9001 0',
 })
 
-with patch('stem.descriptor.remote.get_server_descriptors', 
download_of(server_desc)):
-  with patch('stem.descriptor.remote.get_extrainfo_descriptors', 
download_of(extrainfo_desc)):
+with patch('stem.descriptor.remote.get_server_descriptors', 
_download_of(server_desc)):
+  with patch('stem.descriptor.remote.get_extrainfo_descriptors', 
_download_of(extrainfo_desc)):
 # correctly signed descriptors
 
-with patch('stem.descriptor.remote.get_consensus', 
download_of(consensus_desc)):
+with patch('stem.descriptor.remote.get_consensus', 
_download_of(consensus_desc)):
   with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
 module.validate_relay(fingerprint)
 self.assertEqual(EXPECTED_CHECK_DIGESTS_OK, stdout_mock.getvalue())
 
 # incorrect server descriptor digest
 
-with patch('stem.descriptor.remote.get_consensus', 
download_of(bad_consensus_desc)):
+with patch('stem.descriptor.remote.get_consensus', 
_download_of(bad_consensus_desc)):
   with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
 module.validate_relay(fingerprint)
 self.assertEqual(EXPECTED_CHECK_DIGESTS_BAD % 
server_desc.digest(), stdout_mock.getvalue())
@@ -494,11 +498,35 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual(EXPECTED_OUTDATED_RELAYS, stdout_mock.getvalue())
 
-  def test_persisting_a_consensus(self):
-pass
+  @patch('stem.descriptor.remote.DescriptorDownloader')
+  def test_persisting_a_consensus(self, downloader_mock):
+consensus = NetworkStatusDocumentV3.create(routers = 
(RouterStatusEntryV3.create({
+  'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 71.35.150.29 9001 0',
+}),))
 
-  def test_persisting_a_consensus_with_parse_file(self):
-pass
+downloader_mock().get_consensus = _download_of(consensus)
+
+try:
+  import persisting_a_consensus
+
+  with 

[tor-commits] [stem/master] Test fibonacci examples

2020-10-02 Thread atagar
commit 68ab78c21c15461936050bfaf1908abf033de85d
Author: Damian Johnson 
Date:   Tue Sep 29 14:58:44 2020 -0700

Test fibonacci examples
---
 docs/_static/example/fibonacci_multiprocessing.py | 18 ++---
 docs/_static/example/fibonacci_threaded.py| 24 +--
 test/unit/examples.py | 21 
 3 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/docs/_static/example/fibonacci_multiprocessing.py 
b/docs/_static/example/fibonacci_multiprocessing.py
index e909e169..4ad3fe48 100644
--- a/docs/_static/example/fibonacci_multiprocessing.py
+++ b/docs/_static/example/fibonacci_multiprocessing.py
@@ -7,14 +7,18 @@ def fibonacci(n):
   else:
 return fibonacci(n-2) + fibonacci(n-1)
 
-# calculate fibonacci sequences four times in parallel
+def main():
+  # calculate fibonacci sequences four times in parallel
 
-start_time, threads = time.time(), []
+  start_time, threads = time.time(), []
 
-for i in range(4):
-  threads.append(stem.util.system.DaemonTask(fibonacci, (35,), start = True))
+  for i in range(4):
+threads.append(stem.util.system.DaemonTask(fibonacci, (35,), start = True))
 
-for t in threads:
-  t.join()
+  for t in threads:
+t.join()
 
-print('took %0.1f seconds' % (time.time() - start_time))
+  print('took %0.1f seconds' % (time.time() - start_time))
+
+if __name__ == '__main__':
+  main()
diff --git a/docs/_static/example/fibonacci_threaded.py 
b/docs/_static/example/fibonacci_threaded.py
index f40b7401..0e449122 100644
--- a/docs/_static/example/fibonacci_threaded.py
+++ b/docs/_static/example/fibonacci_threaded.py
@@ -7,18 +7,22 @@ def fibonacci(n):
   else:
 return fibonacci(n-2) + fibonacci(n-1)
 
-# calculate fibonacci sequences four times in parallel
+def main():
+  # calculate fibonacci sequences four times in parallel
 
-start_time, threads = time.time(), []
+  start_time, threads = time.time(), []
 
-for i in range(4):
-  t = threading.Thread(target = fibonacci, args = (35,))
-  t.setDaemon(True)
-  t.start()
+  for i in range(4):
+t = threading.Thread(target = fibonacci, args = (35,))
+t.setDaemon(True)
+t.start()
 
-  threads.append(t)
+threads.append(t)
 
-for t in threads:
-  t.join()
+  for t in threads:
+t.join()
 
-print('took %0.1f seconds' % (time.time() - start_time))
+  print('took %0.1f seconds' % (time.time() - start_time))
+
+if __name__ == '__main__':
+  main()
diff --git a/test/unit/examples.py b/test/unit/examples.py
index d9a3f6fa..07b6ec00 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -578,11 +578,24 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual(EXPECTED_EXIT_USED, stdout_mock.getvalue())
 
-  def test_fibonacci_multiprocessing(self):
-pass
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_fibonacci_multiprocessing(self, stdout_mock):
+# This example intentionally takes a long time (~11 seconds), so replacing
+# the work it does with a no-op.
 
-  def test_fibonacci_threaded(self):
-pass
+with patch('fibonacci_multiprocessing.fibonacci', Mock(return_value = 5)):
+  import fibonacci_multiprocessing
+
+  fibonacci_multiprocessing.main()
+  self.assertEqual('took 0.0 seconds\n', stdout_mock.getvalue())
+
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_fibonacci_threaded(self, stdout_mock):
+with patch('fibonacci_threaded.fibonacci', Mock(return_value = 5)):
+  import fibonacci_threaded
+
+  fibonacci_threaded.main()
+  self.assertEqual('took 0.0 seconds\n', stdout_mock.getvalue())
 
   def test_get_hidden_service_descriptor(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Drop exec_documentation_example helper

2020-10-02 Thread atagar
commit 8f5cf5bf4a4226bc6ff532ef7f642dc39ee942d2
Author: Damian Johnson 
Date:   Sun Sep 27 16:16:45 2020 -0700

Drop exec_documentation_example helper

Previously tests used compile() to run our examples rather than adjusting 
our
path. Both approaches work but what we have now is a tad simpler.
---
 test/unit/tutorial.py | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py
index 472285ad..f35a6b6d 100644
--- a/test/unit/tutorial.py
+++ b/test/unit/tutorial.py
@@ -3,11 +3,9 @@ Tests for the examples given in stem's tutorial.
 """
 
 import io
-import os
 import unittest
 
 import stem.descriptor.remote
-import test
 
 from unittest.mock import Mock, patch
 
@@ -15,7 +13,6 @@ from stem.control import Controller
 from stem.descriptor.router_status_entry import RouterStatusEntryV3
 from stem.descriptor.networkstatus import NetworkStatusDocumentV3
 from stem.descriptor.server_descriptor import RelayDescriptor
-from stem.exit_policy import ExitPolicy
 
 OVER_THE_RIVER_OUTPUT = """\
  * Connecting to tor
@@ -31,14 +28,6 @@ MIRROR_MIRROR_OUTPUT = """\
 """
 
 
-def exec_documentation_example(filename):
-  path = os.path.join(test.STEM_BASE, 'docs', '_static', 'example', filename)
-
-  with open(path) as f:
-code = compile(f.read(), path, 'exec')
-exec(code)
-
-
 class TestTutorial(unittest.TestCase):
   def tearDown(self):
 # Ensure we don't cache a Mock object as our downloader. Otherwise future



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test manual_config_options example

2020-10-02 Thread atagar
commit 51512eb6627a8b945340d5208fab68eb29885f57
Author: Damian Johnson 
Date:   Tue Sep 29 18:10:28 2020 -0700

Test manual_config_options example
---
 docs/_static/example/manual_config_options.py |  2 +-
 test/unit/examples.py | 25 +++--
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/docs/_static/example/manual_config_options.py 
b/docs/_static/example/manual_config_options.py
index 4a503579..336634a3 100644
--- a/docs/_static/example/manual_config_options.py
+++ b/docs/_static/example/manual_config_options.py
@@ -13,7 +13,7 @@ print('Which tor configuration would you like to learn about? 
 (press ctrl+c to
 
 try:
   while True:
-requested_option = raw_input('> ').strip()
+requested_option = input('> ').strip()
 
 if requested_option:
   if requested_option in manual.config_options:
diff --git a/test/unit/examples.py b/test/unit/examples.py
index 12ffb60c..0b4d7082 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -172,6 +172,21 @@ Circuit 10 (GENERAL)
  +- 65242C91BFF30F165DA4D132C81A9EBA94B71D62 (torexit16, 176.67.169.171)
 """
 
+EXPECTED_MANUAL_CONFIG_OPTIONS = """\
+Downloading tor's manual information, please wait...
+  done
+
+Which tor configuration would you like to learn about?  (press ctrl+c to quit)
+
+IPv6Exit 0|1
+Allow clients to use us for IPv6 traffic
+
+Full Description:
+
+If set, and we are an exit node, allow clients to use us for IPv6 traffic. 
When this option is set and ExitRelay is auto, we act as if ExitRelay is 1. 
(Default: 0)
+
+"""
+
 EXPECTED_OUTDATED_RELAYS = """\
 Checking for outdated relays...
 
@@ -704,8 +719,14 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual(EXPECTED_LIST_CIRCUITS, stdout_mock.getvalue())
 
-  def test_manual_config_options(self):
-pass
+  @patch('stem.manual.Manual.from_remote', Mock(return_value = 
stem.manual.Manual.from_cache()))
+  @patch('stem.util.term.format', Mock(side_effect = lambda msg, *args: msg))
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_manual_config_options(self, stdout_mock):
+with patch('builtins.input', Mock(side_effect = ['IPv6Exit', 
KeyboardInterrupt()])):
+  import manual_config_options
+
+self.assertEqual(EXPECTED_MANUAL_CONFIG_OPTIONS, stdout_mock.getvalue())
 
   @patch('stem.descriptor.remote.DescriptorDownloader')
   @patch('sys.stdout', new_callable = io.StringIO)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move tor_descriptors test

2020-10-02 Thread atagar
commit b8ab2cc30cad6850d5a011ecca129b35af47802a
Author: Damian Johnson 
Date:   Mon Sep 28 00:07:20 2020 -0700

Move tor_descriptors test
---
 test/settings.cfg |  1 -
 test/unit/examples.py | 29 ++--
 test/unit/tutorial.py | 74 ---
 3 files changed, 27 insertions(+), 77 deletions(-)

diff --git a/test/settings.cfg b/test/settings.cfg
index 91f287cf..853c4483 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -289,7 +289,6 @@ test.unit_tests
 |test.unit.manual.TestManual
 |test.unit.directory.authority.TestAuthority
 |test.unit.directory.fallback.TestFallback
-|test.unit.tutorial.TestTutorial
 |test.unit.response.add_onion.TestAddOnionResponse
 |test.unit.response.control_message.TestControlMessage
 |test.unit.response.control_line.TestControlLine
diff --git a/test/unit/examples.py b/test/unit/examples.py
index c972c7e9..dc9fc242 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -163,6 +163,12 @@ EXPECTED_RUNNING_HIDDEN_SERVICE = """\
  * Shutting down our hidden service
 """
 
+EXPECTED_TOR_DESCRIPTORS = """\
+1. speedyexit (102.13 KB/s)
+2. speedyexit (102.13 KB/s)
+3. speedyexit (102.13 KB/s)
+"""
+
 EXPECTED_VOTES_BY_BANDWIDTH_AUTHORITIES = """\
 Getting gabelmoo's vote from 
http://131.188.40.189:80/tor/status-vote/current/authority:
   5935 measured entries and 1332 unmeasured
@@ -193,6 +199,11 @@ class TestExamples(unittest.TestCase):
   def tearDown(self):
 sys.path = self.original_path
 
+# Ensure we don't cache a Mock object as our downloader. Otherwise future
+# tests will understandably be very sad. :P
+
+stem.descriptor.remote.SINGLETON_DOWNLOADER = None
+
   def test_runs_everything(self):
 """
 Ensure we have tests for all our examples.
@@ -620,8 +631,22 @@ class TestExamples(unittest.TestCase):
   def test_slow_listener(self):
 pass
 
-  def test_tor_descriptors(self):
-pass
+  @patch('stem.descriptor.remote.DescriptorDownloader')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_tor_descriptors(self, stdout_mock, downloader_mock):
+exit_descriptor = RelayDescriptor.content({'router': 'speedyexit 
149.255.97.109 9001 0 0'}).replace(b'reject *:*', b'accept *:*')
+exit_descriptor = RelayDescriptor(exit_descriptor)
+
+downloader_mock().get_server_descriptors().run.return_value = [
+  exit_descriptor,
+  RelayDescriptor.create(),  # non-exit
+  exit_descriptor,
+  exit_descriptor,
+]
+
+import tor_descriptors
+
+self.assertEqual(EXPECTED_TOR_DESCRIPTORS, stdout_mock.getvalue())
 
   def test_utilities(self):
 pass
diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py
deleted file mode 100644
index e2b621e8..
--- a/test/unit/tutorial.py
+++ /dev/null
@@ -1,74 +0,0 @@
-"""
-Tests for the examples given in stem's tutorial.
-"""
-
-import io
-import unittest
-
-import stem.descriptor.remote
-
-from unittest.mock import patch
-
-from stem.descriptor.server_descriptor import RelayDescriptor
-
-MIRROR_MIRROR_OUTPUT = """\
-1. speedyexit (102.13 KB/s)
-2. speedyexit (102.13 KB/s)
-3. speedyexit (102.13 KB/s)
-"""
-
-
-class TestTutorial(unittest.TestCase):
-  def tearDown(self):
-# Ensure we don't cache a Mock object as our downloader. Otherwise future
-# tests will understandably be very sad. :P
-
-stem.descriptor.remote.SINGLETON_DOWNLOADER = None
-
-  @patch('sys.stdout', new_callable = io.StringIO)
-  @patch('stem.descriptor.remote.DescriptorDownloader')
-  def test_mirror_mirror_on_the_wall_5(self, downloader_mock, stdout_mock):
-def tutorial_example():
-  from stem.descriptor.remote import DescriptorDownloader
-  from stem.util import str_tools
-
-  # provides a mapping of observed bandwidth to the relay nicknames
-  def get_bw_to_relay():
-bw_to_relay = {}
-
-downloader = DescriptorDownloader()
-
-try:
-  for desc in downloader.get_server_descriptors().run():
-if desc.exit_policy.is_exiting_allowed():
-  bw_to_relay.setdefault(desc.observed_bandwidth, 
[]).append(desc.nickname)
-except Exception as exc:
-  print('Unable to retrieve the server descriptors: %s' % exc)
-
-return bw_to_relay
-
-  # prints the top fifteen relays
-
-  bw_to_relay = get_bw_to_relay()
-  count = 1
-
-  for bw_value in sorted(bw_to_relay.keys(), reverse = True):
-for nickname in bw_to_relay[bw_value]:
-  print('%i. %s (%s/s)' % (count, nickname, 
str_tools.size_label(bw_value, 2)))
-  count += 1
-
-  if count > 15:
-return
-
-exit_descriptor = RelayDescriptor.content({'router': 'speedyexit 
149.255.97.109 9001 0 0'}).replace(b'reject *:*', b'accept *:*')
-exit_descriptor = RelayDescriptor(exit_descriptor)
-
-downloader_mock().get_server_descriptors().run.return_value = [
-  exit_descriptor,
-  RelayDescriptor.create(),  # non-exit
-  

[tor-commits] [stem/master] Test ephemeral_hidden_services example

2020-10-02 Thread atagar
commit 31ec07e1bfd259063b5408683b67e2dba8aa674d
Author: Damian Johnson 
Date:   Tue Sep 29 13:43:48 2020 -0700

Test ephemeral_hidden_services example
---
 test/unit/examples.py | 25 +++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index eb9bdb2a..35aa80bb 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -127,6 +127,12 @@ Downloading server descriptor from 1.2.3.4:443...
 router caerSidi 71.35.133.197 9001 0 0
 """
 
+EXPECTED_EPHEMEREAL_HIDDEN_SERVICES = """\
+ * Connecting to tor
+ * Our service is available at my-service.onion, press ctrl+c to quit
+ * Shutting down our hidden service
+"""
+
 EXPECTED_EXIT_USED = """\
 Tracking requests for tor exits. Press 'enter' to end.
 
@@ -515,8 +521,23 @@ class TestExamples(unittest.TestCase):
 download_descriptor.main(['--dirport', '1.2.3.4:443'])
 
self.assertTrue(stdout_mock.getvalue().startswith(EXPECTED_DOWNLOAD_DESCRIPTOR_PREFIX))
 
-  def test_ephemeral_hidden_services(self):
-pass
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_ephemeral_hidden_services(self, stdout_mock, from_port_mock):
+original_modules = dict(sys.modules)
+
+try:
+  sys.modules['flask'] = Mock()
+
+  controller = from_port_mock().__enter__()
+  hidden_service = controller.create_ephemeral_hidden_service()
+  hidden_service.service_id = 'my-service'
+
+  import ephemeral_hidden_services
+
+  self.assertEqual(EXPECTED_EPHEMEREAL_HIDDEN_SERVICES, 
stdout_mock.getvalue())
+finally:
+  sys.modules = original_modules
 
   def test_event_listening(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move running_hidden_service test

2020-10-02 Thread atagar
commit 469a925991acdd3e99cc486215aac673a5f81062
Author: Damian Johnson 
Date:   Sun Sep 27 17:11:24 2020 -0700

Move running_hidden_service test
---
 test/unit/examples.py | 37 +++--
 test/unit/tutorial.py | 76 +--
 2 files changed, 36 insertions(+), 77 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index cadf3048..ef1d9ed9 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -155,6 +155,14 @@ Checking for outdated relays...
 EXPECTED_PERSISTING_A_CONSENSUS = """\
 A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB: caerSidi
 """
+
+EXPECTED_RUNNING_HIDDEN_SERVICE = """\
+ * Connecting to tor
+ * Creating our hidden service in /home/atagar/.tor/hello_world
+ * Our service is available at uxiuaxejc3sxrb6i.onion, press ctrl+c to quit
+ * Shutting down our hidden service
+"""
+
 EXPECTED_VOTES_BY_BANDWIDTH_AUTHORITIES = """\
 Getting gabelmoo's vote from 
http://131.188.40.189:80/tor/status-vote/current/authority:
   5935 measured entries and 1332 unmeasured
@@ -570,8 +578,33 @@ class TestExamples(unittest.TestCase):
   def test_resuming_ephemeral_hidden_service(self):
 pass
 
-  def test_running_hidden_service(self):
-pass
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('shutil.rmtree')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_running_hidden_service(self, stdout_mock, rmtree_mock, 
from_port_mock):
+original_modules = dict(sys.modules)
+
+try:
+  flask_mock = Mock()
+
+  hidden_service_data = Mock()
+  hidden_service_data.hostname = 'uxiuaxejc3sxrb6i.onion'
+
+  controller = from_port_mock().__enter__()
+  controller.get_conf.return_value = '/home/atagar/.tor'
+  controller.create_hidden_service.return_value = hidden_service_data
+
+  sys.modules['flask'] = flask_mock
+
+  import running_hidden_service
+
+  controller.get_conf.assert_called_once_with('DataDirectory', '/tmp')
+  
controller.create_hidden_service.assert_called_once_with('/home/atagar/.tor/hello_world',
 80, target_port = 5000)
+  rmtree_mock.assert_called_once_with('/home/atagar/.tor/hello_world')
+
+  self.assertEqual(EXPECTED_RUNNING_HIDDEN_SERVICE, stdout_mock.getvalue())
+finally:
+  sys.modules = original_modules
 
   def test_saving_and_loading_descriptors(self):
 pass
diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py
index f35a6b6d..d6b6ee3b 100644
--- a/test/unit/tutorial.py
+++ b/test/unit/tutorial.py
@@ -7,20 +7,12 @@ import unittest
 
 import stem.descriptor.remote
 
-from unittest.mock import Mock, patch
+from unittest.mock import patch
 
-from stem.control import Controller
 from stem.descriptor.router_status_entry import RouterStatusEntryV3
 from stem.descriptor.networkstatus import NetworkStatusDocumentV3
 from stem.descriptor.server_descriptor import RelayDescriptor
 
-OVER_THE_RIVER_OUTPUT = """\
- * Connecting to tor
- * Creating our hidden service in /home/atagar/.tor/hello_world
- * Our service is available at uxiuaxejc3sxrb6i.onion, press ctrl+c to quit
- * Shutting down our hidden service
-"""
-
 MIRROR_MIRROR_OUTPUT = """\
 1. speedyexit (102.13 KB/s)
 2. speedyexit (102.13 KB/s)
@@ -35,72 +27,6 @@ class TestTutorial(unittest.TestCase):
 
 stem.descriptor.remote.SINGLETON_DOWNLOADER = None
 
-  @patch('sys.stdout', new_callable = io.StringIO)
-  @patch('shutil.rmtree')
-  @patch('stem.control.Controller.from_port', spec = Controller)
-  def test_over_the_river(self, from_port_mock, rmtree_mock, stdout_mock):
-def tutorial_example(app):
-  import os
-  import shutil
-
-  from stem.control import Controller
-
-  @app.route('/')
-  def index():
-return 'Hi Grandma!'
-
-  print(' * Connecting to tor')
-
-  with Controller.from_port() as controller:
-controller.authenticate()
-
-# All hidden services have a directory on disk. Lets put ours in tor's 
data
-# directory.
-
-hidden_service_dir = os.path.join(controller.get_conf('DataDirectory', 
'/tmp'), 'hello_world')
-
-# Create a hidden service where visitors of port 80 get redirected to 
local
-# port 5000 (this is where flask runs by default).
-
-print(' * Creating our hidden service in %s' % hidden_service_dir)
-result = controller.create_hidden_service(hidden_service_dir, 80, 
target_port = 5000)
-
-# The hostname is only available we can read the hidden service 
directory.
-# This requires us to be running with the same user as tor.
-
-if result.hostname:
-  print(' * Our service is available at %s, press ctrl+c to quit' % 
result.hostname)
-else:
-  print(" * Unable to determine our service's hostname, probably due 
to being unable to read the hidden service 

[tor-commits] [stem/master] Test resuming_ephemeral_hidden_service example

2020-10-02 Thread atagar
commit 30e95d4feb4a72cdb62dfef963236b7368e7c7e9
Author: Damian Johnson 
Date:   Fri Oct 2 12:31:38 2020 -0700

Test resuming_ephemeral_hidden_service example
---
 .../example/resuming_ephemeral_hidden_service.py   |  2 +-
 test/unit/examples.py  | 22 --
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/docs/_static/example/resuming_ephemeral_hidden_service.py 
b/docs/_static/example/resuming_ephemeral_hidden_service.py
index d2073f03..3277bce2 100644
--- a/docs/_static/example/resuming_ephemeral_hidden_service.py
+++ b/docs/_static/example/resuming_ephemeral_hidden_service.py
@@ -19,5 +19,5 @@ with Controller.from_port() as controller:
 service = controller.create_ephemeral_hidden_service({80: 5000}, key_type 
= key_type, key_content = key_content, await_publication = True)
 print("Resumed %s.onion" % service.service_id)
 
-  raw_input('press any key to shut the service down...')
+  input('press any key to shut the service down...')
   controller.remove_ephemeral_hidden_service(service.service_id)
diff --git a/test/unit/examples.py b/test/unit/examples.py
index e1c223bf..0b66c124 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -868,8 +868,26 @@ class TestExamples(unittest.TestCase):
   relay_connections.main([])
   self.assertEqual(EXPECTED_RELAY_CONNECTIONS, stdout_mock.getvalue())
 
-  def test_resuming_ephemeral_hidden_service(self):
-pass
+  @patch('builtins.input', Mock())
+  @patch('os.path.expanduser', Mock(return_value = '/tmp/stem_hs_test'))
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_resuming_ephemeral_hidden_service(self, stdout_mock, 
from_port_mock):
+hs_response = 
'250-ServiceID=gfzprpioee3hoppz\n250-PrivateKey=RSA1024:MIICXgIB\n250 OK'
+
+controller = from_port_mock().__enter__()
+controller.create_ephemeral_hidden_service.return_value = 
ControlMessage.from_str(hs_response, 'ADD_ONION', normalize = True)
+
+try:
+  import resuming_ephemeral_hidden_service
+
+  with open('/tmp/stem_hs_test') as key_file:
+self.assertEqual('RSA1024:MIICXgIB', key_file.read())
+
+  self.assertEqual('Started a new hidden service with the address of 
gfzprpioee3hoppz.onion\n', stdout_mock.getvalue())
+finally:
+  if os.path.exists('/tmp/stem_hs_test'):
+os.remove('/tmp/stem_hs_test')
 
   @patch('stem.control.Controller.from_port', spec = Controller)
   @patch('shutil.rmtree')



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test get_hidden_service_descriptor example

2020-10-02 Thread atagar
commit ae6a045d7808800451e1372f10e90e8e5b063bd8
Author: Damian Johnson 
Date:   Tue Sep 29 15:02:59 2020 -0700

Test get_hidden_service_descriptor example
---
 test/unit/examples.py | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 07b6ec00..df46a30c 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -18,6 +18,7 @@ import test.require
 from stem.control import Controller
 from stem.descriptor.bandwidth_file import BandwidthFile
 from stem.descriptor.extrainfo_descriptor import RelayExtraInfoDescriptor
+from stem.descriptor.hidden_service import HiddenServiceDescriptorV2
 from stem.descriptor.networkstatus import NetworkStatusDocumentV3
 from stem.descriptor.router_status_entry import RouterStatusEntryV2, 
RouterStatusEntryV3
 from stem.descriptor.server_descriptor import RelayDescriptor
@@ -597,8 +598,15 @@ class TestExamples(unittest.TestCase):
   fibonacci_threaded.main()
   self.assertEqual('took 0.0 seconds\n', stdout_mock.getvalue())
 
-  def test_get_hidden_service_descriptor(self):
-pass
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_get_hidden_service_descriptor(self, stdout_mock, from_port_mock):
+controller = from_port_mock().__enter__()
+controller.get_hidden_service_descriptor.return_value = 
HiddenServiceDescriptorV2.create()
+
+import get_hidden_service_descriptor
+
+
self.assertTrue(stdout_mock.getvalue().startswith('rendezvous-service-descriptor
 '))
 
   @patch('stem.control.Controller.from_port', spec = Controller)
   @patch('sys.stdout', new_callable = io.StringIO)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test broken_listener example

2020-10-02 Thread atagar
commit f8e075cdf7782ad5bee036274d51b43d99cf2f34
Author: Damian Johnson 
Date:   Tue Sep 22 16:46:47 2020 -0700

Test broken_listener example

Ooph! Despite being a tiny test for a tiny example this took me hours to get
the mocks right. On reflection though this is pretty straight forward.
is_alive() must be mocked so the 'with' clause doesn't attempt to connect to
something.
---
 test/unit/examples.py | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 124ca3c7..2f664fd3 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -8,11 +8,14 @@ import os
 import sys
 import unittest
 
+import stem.socket
 import stem.util.system
 import test
 
+from stem.control import Controller
 from stem.descriptor.bandwidth_file import BandwidthFile
-from unittest.mock import patch
+from stem.response import ControlMessage
+from unittest.mock import Mock, patch
 
 EXAMPLE_DIR = os.path.join(test.STEM_BASE, 'docs', '_static', 'example')
 DESC_DIR = os.path.join(test.STEM_BASE, 'test', 'unit', 'descriptor', 'data')
@@ -153,8 +156,23 @@ class TestExamples(unittest.TestCase):
   module.measure_fraction_relays_exit_80_microdescriptors(path)
   self.assertTrue(stdout_mock.getvalue().startswith(expected_prefix))
 
-  def test_broken_listener(self):
-pass
+  @patch('time.sleep')
+  @patch('stem.control.Controller.authenticate', Mock())
+  @patch('stem.control.Controller.is_alive', Mock(return_value = True))
+  @patch('stem.control.Controller.from_port')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_broken_listener(self, stdout_mock, from_port_mock, sleep_mock):
+controller = Controller(stem.socket.ControlSocket())
+from_port_mock.return_value = controller
+
+# emits a BW event when the example runs time.sleep()
+
+bw_event = ControlMessage.from_str('650 BW 15 25', 'EVENT', normalize = 
True)
+sleep_mock.side_effect = lambda duration: 
controller._handle_event(bw_event)
+
+import_example('broken_listener')
+
+self.assertEqual('start of broken_handler\n', stdout_mock.getvalue())
 
   def test_check_digests(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test benchmark_server_descriptor_stem example

2020-10-02 Thread atagar
commit fc902a4917b3fb96e6c11b71a8f24737bbae221f
Author: Damian Johnson 
Date:   Mon Sep 21 16:28:30 2020 -0700

Test benchmark_server_descriptor_stem example
---
 test/unit/examples.py | 33 +++--
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 12e3d68f..6a00d9b7 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -33,20 +33,25 @@ Relay BD4172533C3F7271ABCCD9F057E06FD91547C42B
 
 """
 
+EXPECTED_BENCHMARK_SERVER_DESC_PREFIX = """\
+Finished measure_average_advertised_bandwidth('%s')
+  Total time: 0 seconds
+  Processed server descriptors: 5
+  Average advertised bandwidth: 313183
+  Time per server descriptor:
+""".rstrip()
 
-def run_example(module):
+
+def import_example(module_name):
   """
-  Invoke the given example, returning its stdout.
+  Import this example module.
   """
 
   original_path = list(sys.path)
   sys.path.append(EXAMPLE_DIR)
 
   try:
-with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
-  importlib.import_module(module)
-
-return stdout_mock.getvalue()
+return importlib.import_module(module_name)
   finally:
 sys.path = original_path
 
@@ -70,7 +75,8 @@ class TestExamples(unittest.TestCase):
   self.fail("Changed our examples directory? The following are untested: 
%s" % ', '.join(missing))
 
   @patch('stem.descriptor.remote.get_bandwidth_file')
-  def test_bandwidth_stats(self, get_bandwidth_file_mock):
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_bandwidth_stats(self, stdout_mock, get_bandwidth_file_mock):
 get_bandwidth_file_mock().run.return_value = [BandwidthFile.create({
   'content': [
 'bw=1 bw_mean=807445 bw_median=911047 consensus_bandwidth=119 
node_id=$FDCF49562E65B1CC219410009BD48A9EED387C77',
@@ -78,10 +84,17 @@ class TestExamples(unittest.TestCase):
   ],
 })]
 
-self.assertEqual(EXPECTED_BANDWIDTH_STATS, run_example('bandwidth_stats'))
+import_example('bandwidth_stats')
+self.assertEqual(EXPECTED_BANDWIDTH_STATS, stdout_mock.getvalue())
 
-  def test_benchmark_server_descriptor_stem(self):
-pass
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_benchmark_server_descriptor_stem(self, stdout_mock):
+path = os.path.join(test.STEM_BASE, 'test', 'unit', 'descriptor', 'data', 
'collector', 'server-descriptors-2005-12-cropped.tar')
+
+module = import_example('benchmark_server_descriptor_stem')
+module.measure_average_advertised_bandwidth(path)
+
+
self.assertTrue(stdout_mock.getvalue().startswith(EXPECTED_BENCHMARK_SERVER_DESC_PREFIX
 % path))
 
   def test_benchmark_stem(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Skip client usage tests

2020-10-02 Thread atagar
commit 632c13d84decb132cdf57c9b27fe54bc668ec86c
Author: Damian Johnson 
Date:   Wed Sep 23 16:36:28 2020 -0700

Skip client usage tests

There's not much code within these that we can test (it would effectively be
wholly mocks).
---
 test/settings.cfg |  1 +
 test/unit/examples.py | 46 --
 2 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/test/settings.cfg b/test/settings.cfg
index a7bf1e1c..26561327 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -213,6 +213,7 @@ pyflakes.ignore test/require.py => 
'cryptography.hazmat.primitives.ciphers.Ciphe
 pyflakes.ignore test/require.py => 
'cryptography.hazmat.primitives.ciphers.modes' imported but unused
 pyflakes.ignore test/require.py => 
'cryptography.hazmat.primitives.serialization.load_der_public_key' imported but 
unused
 pyflakes.ignore test/require.py => 
'cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey' imported 
but unused
+pyflakes.ignore test/unit/examples.py => * imported but unused
 pyflakes.ignore test/unit/response/events.py => 'from stem import *' used; 
unable to detect undefined names
 pyflakes.ignore test/unit/response/events.py => *may be undefined, or defined 
from star imports: stem
 pyflakes.ignore test/integ/interpreter.py => 'readline' imported but unused
diff --git a/test/unit/examples.py b/test/unit/examples.py
index ba75a98c..566611c5 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -4,7 +4,6 @@ Exercise the code in our examples directory.
 
 import base64
 import binascii
-import importlib
 import io
 import os
 import sys
@@ -26,6 +25,13 @@ from unittest.mock import Mock, patch
 EXAMPLE_DIR = os.path.join(test.STEM_BASE, 'docs', '_static', 'example')
 DESC_DIR = os.path.join(test.STEM_BASE, 'test', 'unit', 'descriptor', 'data')
 
+UNTESTED = (
+  # client usage demos don't have much non-stem code
+
+  'client_usage_using_pycurl',
+  'client_usage_using_socksipy',
+)
+
 EXPECTED_BANDWIDTH_STATS = """\
 Relay FDCF49562E65B1CC219410009BD48A9EED387C77
   bw = 1
@@ -86,21 +92,14 @@ Extrainfo descriptor digest is correct
 """
 
 
-def import_example(module_name):
-  """
-  Import this example module.
-  """
-
-  original_path = list(sys.path)
-  sys.path.append(EXAMPLE_DIR)
-
-  try:
-return importlib.import_module(module_name)
-  finally:
-sys.path = original_path
+class TestExamples(unittest.TestCase):
+  def setUp(self):
+self.original_path = list(sys.path)
+sys.path.append(EXAMPLE_DIR)
 
+  def tearDown(self):
+sys.path = self.original_path
 
-class TestExamples(unittest.TestCase):
   def test_runs_everything(self):
 """
 Ensure we have tests for all our examples.
@@ -110,7 +109,7 @@ class TestExamples(unittest.TestCase):
 tested_examples = set([method[5:] for method in dir(self) if 
method.startswith('test_') and method != 'test_runs_everything'])
 
 extra = sorted(tested_examples.difference(all_examples))
-missing = sorted(all_examples.difference(tested_examples))
+missing = 
sorted(all_examples.difference(tested_examples).difference(UNTESTED))
 
 if extra:
   self.fail("Changed our examples directory? We test the following which 
are not present: %s" % ', '.join(extra))
@@ -128,21 +127,22 @@ class TestExamples(unittest.TestCase):
   ],
 })]
 
-import_example('bandwidth_stats')
+import bandwidth_stats
 self.assertEqual(EXPECTED_BANDWIDTH_STATS, stdout_mock.getvalue())
 
   @patch('sys.stdout', new_callable = io.StringIO)
   def test_benchmark_server_descriptor_stem(self, stdout_mock):
+import benchmark_server_descriptor_stem as module
+
 path = os.path.join(DESC_DIR, 'collector', 
'server-descriptors-2005-12-cropped.tar')
 expected_prefix = EXPECTED_SERVER_DESC_BENCHMARK_PREFIX % path
 
-module = import_example('benchmark_server_descriptor_stem')
 module.measure_average_advertised_bandwidth(path)
 
 self.assertTrue(stdout_mock.getvalue().startswith(expected_prefix))
 
   def test_benchmark_stem(self):
-module = import_example('benchmark_stem')
+import benchmark_stem as module
 
 with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
   path = os.path.join(DESC_DIR, 'collector', 
'server-descriptors-2005-12-cropped.tar')
@@ -186,7 +186,7 @@ class TestExamples(unittest.TestCase):
 bw_event = ControlMessage.from_str('650 BW 15 25', 'EVENT', normalize = 
True)
 sleep_mock.side_effect = lambda duration: 
controller._handle_event(bw_event)
 
-import_example('broken_listener')
+import broken_listener
 
 self.assertEqual('start of broken_handler\n', stdout_mock.getvalue())
 
@@ -197,7 +197,7 @@ class TestExamples(unittest.TestCase):
   query.run.return_value = [desc]
   return Mock(return_value = query)
 
-module = import_example('check_digests')
+import check_digests as module
 fingerprint = 'A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB'
 
 

[tor-commits] [stem/master] Fix server descriptor fingerprint crypto check

2020-10-02 Thread atagar
commit b487951b3a21b758b94baf23eaac54182cf6bdec
Author: Damian Johnson 
Date:   Sat Sep 26 15:13:24 2020 -0700

Fix server descriptor fingerprint crypto check

Fixing a server descriptor bug where checking our fingerprint didn't honor 
our
skip_crypto_validation argument. This bug made it difficult to create
descriptors with a preset fingerprint...

  >>> RelayDescriptor.create({'fingerprint': '4F0C 867D F0EF 6816 0568 C826 
838F 482C EA7C FE44'})
  ...
  ValueError: Fingerprint does not match the hash of our signing key
  (fingerprint: 4f0c867df0ef68160568c826838f482cea7cfe44, signing key hash:
  8f54270a36526ab35895d5f899b6ae4059faecb3)
---
 stem/descriptor/server_descriptor.py | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/stem/descriptor/server_descriptor.py 
b/stem/descriptor/server_descriptor.py
index e49688e1..baa14969 100644
--- a/stem/descriptor/server_descriptor.py
+++ b/stem/descriptor/server_descriptor.py
@@ -762,13 +762,13 @@ class RelayDescriptor(ServerDescriptor):
 super(RelayDescriptor, self).__init__(raw_contents, validate)
 
 if validate:
-  if self.fingerprint:
-key_hash = hashlib.sha1(_bytes_for_block(self.signing_key)).hexdigest()
+  if not skip_crypto_validation:
+if self.fingerprint:
+  key_hash = 
hashlib.sha1(_bytes_for_block(self.signing_key)).hexdigest()
 
-if key_hash != self.fingerprint.lower():
-  raise ValueError('Fingerprint does not match the hash of our signing 
key (fingerprint: %s, signing key hash: %s)' % (self.fingerprint.lower(), 
key_hash))
+  if key_hash != self.fingerprint.lower():
+raise ValueError('Fingerprint does not match the hash of our 
signing key (fingerprint: %s, signing key hash: %s)' % 
(self.fingerprint.lower(), key_hash))
 
-  if not skip_crypto_validation:
 try:
   signed_digest = self._digest_for_signature(self.signing_key, 
self.signature)
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test bandwidth_stats example

2020-10-02 Thread atagar
commit be47ff8ffd485a857b3c30ed495bf5ed1e7ff5c1
Author: Damian Johnson 
Date:   Sun Sep 20 16:53:08 2020 -0700

Test bandwidth_stats example
---
 test/unit/examples.py | 60 ++-
 1 file changed, 50 insertions(+), 10 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index ee59a137..12e3d68f 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -2,6 +2,8 @@
 Exercise the code in our examples directory.
 """
 
+import importlib
+import io
 import os
 import sys
 import unittest
@@ -9,23 +11,53 @@ import unittest
 import stem.util.system
 import test
 
+from stem.descriptor.bandwidth_file import BandwidthFile
+from unittest.mock import patch
+
+EXAMPLE_DIR = os.path.join(test.STEM_BASE, 'docs', '_static', 'example')
+
+EXPECTED_BANDWIDTH_STATS = """\
+Relay FDCF49562E65B1CC219410009BD48A9EED387C77
+  bw = 1
+  bw_mean = 807445
+  bw_median = 911047
+  consensus_bandwidth = 119
+  node_id = $FDCF49562E65B1CC219410009BD48A9EED387C77
+
+Relay BD4172533C3F7271ABCCD9F057E06FD91547C42B
+  bw = 1
+  bw_mean = 631049
+  bw_median = 622052
+  consensus_bandwidth = 55000
+  node_id = $BD4172533C3F7271ABCCD9F057E06FD91547C42B
+
+"""
 
-class TestExamples(unittest.TestCase):
-  def setUp(self):
-self.original_path = list(sys.path)
-self.example_dir = os.path.join(test.STEM_BASE, 'docs', '_static', 
'example')
 
-sys.path.append(self.example_dir)
+def run_example(module):
+  """
+  Invoke the given example, returning its stdout.
+  """
 
-  def tearDown(self):
-sys.path = self.original_path
+  original_path = list(sys.path)
+  sys.path.append(EXAMPLE_DIR)
 
+  try:
+with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
+  importlib.import_module(module)
+
+return stdout_mock.getvalue()
+  finally:
+sys.path = original_path
+
+
+class TestExamples(unittest.TestCase):
   def test_runs_everything(self):
 """
 Ensure we have tests for all our examples.
 """
 
-all_examples = set([os.path.basename(path)[:-3] for path in 
stem.util.system.files_with_suffix(self.example_dir, '.py')])
+all_examples = set([os.path.basename(path)[:-3] for path in 
stem.util.system.files_with_suffix(EXAMPLE_DIR, '.py')])
 tested_examples = set([method[5:] for method in dir(self) if 
method.startswith('test_') and method != 'test_runs_everything'])
 
 extra = sorted(tested_examples.difference(all_examples))
@@ -37,8 +69,16 @@ class TestExamples(unittest.TestCase):
 if missing:
   self.fail("Changed our examples directory? The following are untested: 
%s" % ', '.join(missing))
 
-  def test_bandwidth_stats(self):
-pass
+  @patch('stem.descriptor.remote.get_bandwidth_file')
+  def test_bandwidth_stats(self, get_bandwidth_file_mock):
+get_bandwidth_file_mock().run.return_value = [BandwidthFile.create({
+  'content': [
+'bw=1 bw_mean=807445 bw_median=911047 consensus_bandwidth=119 
node_id=$FDCF49562E65B1CC219410009BD48A9EED387C77',
+'bw=1 bw_mean=631049 bw_median=622052 consensus_bandwidth=55000 
node_id=$BD4172533C3F7271ABCCD9F057E06FD91547C42B',
+  ],
+})]
+
+self.assertEqual(EXPECTED_BANDWIDTH_STATS, run_example('bandwidth_stats'))
 
   def test_benchmark_server_descriptor_stem(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test benchmark_stem example

2020-10-02 Thread atagar
commit 4497148d0be8b267e032d8867c082a3588529581
Author: Damian Johnson 
Date:   Mon Sep 21 17:26:30 2020 -0700

Test benchmark_stem example

Caught our first bug in our example code... of sorts. This adds a
'descriptor_type' argument to benchmark_stem.py because CollecTor
microdescriptor archives contain a mixture of consensuses and 
microdescriptors.
---
 docs/_static/example/benchmark_stem.py | 11 +++---
 test/unit/examples.py  | 62 +++---
 2 files changed, 64 insertions(+), 9 deletions(-)

diff --git a/docs/_static/example/benchmark_stem.py 
b/docs/_static/example/benchmark_stem.py
index 8b71d730..7094c3dd 100644
--- a/docs/_static/example/benchmark_stem.py
+++ b/docs/_static/example/benchmark_stem.py
@@ -60,7 +60,7 @@ def measure_fraction_relays_exit_80_microdescriptors(path):
   start_time = time.time()
   exits, count = 0, 0
 
-  for desc in stem.descriptor.parse_file(path):
+  for desc in stem.descriptor.parse_file(path, descriptor_type = 
'microdescriptor 1.0'):
 if desc.exit_policy.can_exit_to(port = 80):
   exits += 1
 
@@ -74,8 +74,9 @@ def measure_fraction_relays_exit_80_microdescriptors(path):
   print('  Time per microdescriptor: %0.5f seconds' % (runtime / count))
   print('')
 
-measure_average_advertised_bandwidth('/home/atagar/Desktop/server-descriptors-2015-11.tar')
-measure_countries_v3_requests('/home/atagar/Desktop/extra-infos-2015-11.tar')
-measure_average_relays_exit('/home/atagar/Desktop/consensuses-2015-11.tar')
-measure_fraction_relays_exit_80_microdescriptors('/home/atagar/Desktop/microdescs-2015-11.tar')
+if __name__ == '__main__':
+  
measure_average_advertised_bandwidth('/home/atagar/Desktop/server-descriptors-2015-11.tar')
+  measure_countries_v3_requests('/home/atagar/Desktop/extra-infos-2015-11.tar')
+  measure_average_relays_exit('/home/atagar/Desktop/consensuses-2015-11.tar')
+  
measure_fraction_relays_exit_80_microdescriptors('/home/atagar/Desktop/microdescs-2015-11.tar')
 
diff --git a/test/unit/examples.py b/test/unit/examples.py
index 6a00d9b7..124ca3c7 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -15,6 +15,7 @@ from stem.descriptor.bandwidth_file import BandwidthFile
 from unittest.mock import patch
 
 EXAMPLE_DIR = os.path.join(test.STEM_BASE, 'docs', '_static', 'example')
+DESC_DIR = os.path.join(test.STEM_BASE, 'test', 'unit', 'descriptor', 'data')
 
 EXPECTED_BANDWIDTH_STATS = """\
 Relay FDCF49562E65B1CC219410009BD48A9EED387C77
@@ -33,7 +34,7 @@ Relay BD4172533C3F7271ABCCD9F057E06FD91547C42B
 
 """
 
-EXPECTED_BENCHMARK_SERVER_DESC_PREFIX = """\
+EXPECTED_SERVER_DESC_BENCHMARK_PREFIX = """\
 Finished measure_average_advertised_bandwidth('%s')
   Total time: 0 seconds
   Processed server descriptors: 5
@@ -41,6 +42,30 @@ Finished measure_average_advertised_bandwidth('%s')
   Time per server descriptor:
 """.rstrip()
 
+EXPECTED_EXTRAINFO_BENCHMARK_PREFIX = """\
+Finished measure_countries_v3_requests('%s')
+  Total time: 0 seconds
+  Processed extrainfo descriptors: 7
+  Number of countries: 6
+  Time per extrainfo descriptor:
+""".rstrip()
+
+EXPECTED_CONSENSUS_BENCHMARK_PREFIX = """\
+Finished measure_average_relays_exit('%s')
+  Total time: 0 seconds
+  Processed 2 consensuses with 243 router status entries
+  Total exits: 28 (0.12%%)
+  Time per consensus:
+""".rstrip()
+
+EXPECTED_MICRODESC_BENCHMARK_PREFIX = """\
+Finished measure_fraction_relays_exit_80_microdescriptors('%s')
+  Total time: 0 seconds
+  Processed microdescriptors: 3
+  Total exits to port 80: 1 (0.33%%)
+  Time per microdescriptor:
+""".rstrip()
+
 
 def import_example(module_name):
   """
@@ -89,15 +114,44 @@ class TestExamples(unittest.TestCase):
 
   @patch('sys.stdout', new_callable = io.StringIO)
   def test_benchmark_server_descriptor_stem(self, stdout_mock):
-path = os.path.join(test.STEM_BASE, 'test', 'unit', 'descriptor', 'data', 
'collector', 'server-descriptors-2005-12-cropped.tar')
+path = os.path.join(DESC_DIR, 'collector', 
'server-descriptors-2005-12-cropped.tar')
+expected_prefix = EXPECTED_SERVER_DESC_BENCHMARK_PREFIX % path
 
 module = import_example('benchmark_server_descriptor_stem')
 module.measure_average_advertised_bandwidth(path)
 
-
self.assertTrue(stdout_mock.getvalue().startswith(EXPECTED_BENCHMARK_SERVER_DESC_PREFIX
 % path))
+self.assertTrue(stdout_mock.getvalue().startswith(expected_prefix))
 
   def test_benchmark_stem(self):
-pass
+module = import_example('benchmark_stem')
+
+with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
+  path = os.path.join(DESC_DIR, 'collector', 
'server-descriptors-2005-12-cropped.tar')
+  expected_prefix = EXPECTED_SERVER_DESC_BENCHMARK_PREFIX % path
+
+  module.measure_average_advertise

[tor-commits] [stem/master] Move exit_used test

2020-10-02 Thread atagar
commit 87446136328bddbbd0cbecf931349a4cdd029518
Author: Damian Johnson 
Date:   Sat Sep 26 23:08:51 2020 -0700

Move exit_used test

Seriously? I copy-pasted the tutorial example into our test? That is...
embarrasing.
---
 docs/_static/example/exit_used.py |  2 +-
 test/unit/examples.py | 52 +---
 test/unit/tutorial_examples.py| 63 ---
 3 files changed, 43 insertions(+), 74 deletions(-)

diff --git a/docs/_static/example/exit_used.py 
b/docs/_static/example/exit_used.py
index 9a16c130..fde2db84 100644
--- a/docs/_static/example/exit_used.py
+++ b/docs/_static/example/exit_used.py
@@ -13,7 +13,7 @@ def main():
 stream_listener = functools.partial(stream_event, controller)
 controller.add_event_listener(stream_listener, EventType.STREAM)
 
-raw_input()  # wait for user to press enter
+input()  # wait for user to press enter
 
 
 def stream_event(controller, event):
diff --git a/test/unit/examples.py b/test/unit/examples.py
index 30375ea3..efdac292 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -4,6 +4,7 @@ Exercise the code in our examples directory.
 
 import base64
 import binascii
+import functools
 import io
 import os
 import sys
@@ -104,6 +105,17 @@ EXPECTED_COLLECTOR_READING = """\
   caerSidi (4F0C867DF0EF68160568C826838F482CEA7CFE44)
 """
 
+EXPECTED_EXIT_USED = """\
+Tracking requests for tor exits. Press 'enter' to end.
+
+Exit relay for our connection to 64.15.112.44:80
+  address: 31.172.30.2:443
+  fingerprint: A59E1E7C7EAEE083D756EE1FF6EC31CA3D8651D7
+  nickname: chaoscomputerclub19
+  locale: unknown
+
+"""
+
 EXPECTED_LIST_CIRCUITS = """\
 
 Circuit 4 (GENERAL)
@@ -123,6 +135,12 @@ Circuit 10 (GENERAL)
 """
 
 
+def _make_circ_event(circ_id, hop1, hop2, hop3):
+  path = '$%s=%s,$%s=%s,$%s=%s' % (hop1[0], hop1[1], hop2[0], hop2[1], 
hop3[0], hop3[1])
+  content = '650 CIRC %i BUILT %s PURPOSE=GENERAL' % (circ_id, path)
+  return ControlMessage.from_str(content, 'EVENT', normalize = True)
+
+
 class TestExamples(unittest.TestCase):
   def setUp(self):
 self.original_path = list(sys.path)
@@ -328,8 +346,27 @@ class TestExamples(unittest.TestCase):
   def test_event_listening(self):
 pass
 
-  def test_exit_used(self):
-pass
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_exit_used(self, stdout_mock, from_port_mock):
+path_1 = ('9EA317EECA56BDF30CAEB208A253FB456EDAB1A0', 'bolobolo1')
+path_2 = ('00C2C2A16AEDB51D5E5FB7D6168FC66B343D822F', 'ph3x')
+path_3 = ('A59E1E7C7EAEE083D756EE1FF6EC31CA3D8651D7', 
'chaoscomputerclub19')
+
+event = ControlMessage.from_str('650 STREAM 15 SUCCEEDED 3 
64.15.112.44:80', 'EVENT', normalize = True)
+r_line = '%s pZ4efH6u4IPXVu4f9uwxyj2GUdc= oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 31.172.30.2 443 0'
+
+controller = from_port_mock().__enter__()
+controller.get_circuit.return_value = _make_circ_event(1, path_1, path_2, 
path_3)
+controller.get_network_status.return_value = 
RouterStatusEntryV3.create({'r': r_line % path_3[1]})
+controller.get_info.return_value = 'unknown'
+
+import exit_used
+
+with patch('builtins.input', Mock(side_effect = 
functools.partial(exit_used.stream_event, controller, event))):
+  exit_used.main()
+
+self.assertEqual(EXPECTED_EXIT_USED, stdout_mock.getvalue())
 
   def test_fibonacci_multiprocessing(self):
 pass
@@ -349,11 +386,6 @@ class TestExamples(unittest.TestCase):
   @patch('stem.control.Controller.from_port', spec = Controller)
   @patch('sys.stdout', new_callable = io.StringIO)
   def test_list_circuits(self, stdout_mock, from_port_mock):
-def _get_circ_event(circ_id, hop1, hop2, hop3):
-  path = '$%s=%s,$%s=%s,$%s=%s' % (hop1[0], hop1[1], hop2[0], hop2[1], 
hop3[0], hop3[1])
-  content = '650 CIRC %i BUILT %s PURPOSE=GENERAL' % (circ_id, path)
-  return ControlMessage.from_str(content, 'EVENT', normalize = True)
-
 path_1 = ('B1FA7D51B8B6F0CB585D944F450E7C06EDE7E44C', 'ByTORAndTheSnowDog')
 path_2 = ('0DD9935C5E939CFA1E07B8DDA6D91C1A2A9D9338', 'afo02')
 path_3 = ('DB3B1CFBD3E4D97B84B548ADD5B9A31451EEC4CC', 'edwardsnowden3')
@@ -362,9 +394,9 @@ class TestExamples(unittest.TestCase):
 path_6 = ('00C2C2A16AEDB51D5E5FB7D6168FC66B343D822F', 'ph3x')
 path_7 = ('65242C91BFF30F165DA4D132C81A9EBA94B71D62', 'torexit16')
 
-circuit_4 = _get_circ_event(4, path_1, path_2, path_3)
-circuit_6 = _get_circ_event(6, path_1, path_4, path_5)
-circuit_10 = _get_circ_event(10, path_1, path_6, path_7)
+circuit_4 = _make_circ_event(4, path_1, path_2, path_3)
+circuit_6 = _make_circ_event(6, path_1, path_4, path_5)
+circuit_10 = _make_circ_event(10, path_1, path_6, path_7)
 
 controller = from_port_mock().__enter__()
 controller.get_circuits.return_value = [circuit_4, circuit_6, circuit_10]
diff --git 

[tor-commits] [stem/master] Hide doctest verbosity

2020-10-02 Thread atagar
commit ba660041d599de724a223fa25c219629d25da4be
Author: Damian Johnson 
Date:   Sun Sep 20 13:35:20 2020 -0700

Hide doctest verbosity

Python's doctest module examines our system argv, printing verbose (and
unhelpfully confusing) assertion information when we have a '-v' argument...

  https://docs.python.org/3/library/doctest.html#doctest.testfile

That's fine, but run_tests.py separately accepts a '-v' argument so 
explicitly
disabling doctest verbosity.
---
 test/unit/doctest.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/unit/doctest.py b/test/unit/doctest.py
index 40791cf3..791e98b4 100644
--- a/test/unit/doctest.py
+++ b/test/unit/doctest.py
@@ -55,7 +55,7 @@ class TestDocumentation(unittest.TestCase):
 is_failed = False
 
 for path in stem.util.system.files_with_suffix(stem_dir, '.py'):
-  args = {'module_relative': False}
+  args = {'module_relative': False, 'verbose': False}
   test_run = None
 
   if path.endswith('/stem/util/conf.py'):



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Stub example directory tests

2020-10-02 Thread atagar
commit 4451830442de64596c89e9d289718ebc03313e2c
Author: Damian Johnson 
Date:   Sun Sep 20 15:02:11 2020 -0700

Stub example directory tests

Code within our example directory are untested. Stubbing a test module to
remedy that.
---
 docs/_static/example/relay_connections.py |   0
 test/settings.cfg |   1 +
 test/unit/doctest.py  |   2 +-
 test/unit/examples.py | 173 ++
 4 files changed, 175 insertions(+), 1 deletion(-)

diff --git a/docs/_static/example/relay_connections.py 
b/docs/_static/example/relay_connections.py
old mode 100755
new mode 100644
diff --git a/test/settings.cfg b/test/settings.cfg
index b1d26d92..a7bf1e1c 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -314,6 +314,7 @@ test.unit_tests
 |test.unit.interpreter.autocomplete.TestAutocompletion
 |test.unit.interpreter.help.TestHelpResponses
 |test.unit.interpreter.commands.TestInterpreterCommands
+|test.unit.examples.TestExamples
 |test.unit.doctest.TestDocumentation
 
 test.integ_tests
diff --git a/test/unit/doctest.py b/test/unit/doctest.py
index 791e98b4..f72d845f 100644
--- a/test/unit/doctest.py
+++ b/test/unit/doctest.py
@@ -1,5 +1,5 @@
 """
-Tests examples from our documentation.
+Test inline examples from our documentation.
 """
 
 import doctest
diff --git a/test/unit/examples.py b/test/unit/examples.py
new file mode 100644
index ..ee59a137
--- /dev/null
+++ b/test/unit/examples.py
@@ -0,0 +1,173 @@
+"""
+Exercise the code in our examples directory.
+"""
+
+import os
+import sys
+import unittest
+
+import stem.util.system
+import test
+
+
+class TestExamples(unittest.TestCase):
+  def setUp(self):
+self.original_path = list(sys.path)
+self.example_dir = os.path.join(test.STEM_BASE, 'docs', '_static', 
'example')
+
+sys.path.append(self.example_dir)
+
+  def tearDown(self):
+sys.path = self.original_path
+
+  def test_runs_everything(self):
+"""
+Ensure we have tests for all our examples.
+"""
+
+all_examples = set([os.path.basename(path)[:-3] for path in 
stem.util.system.files_with_suffix(self.example_dir, '.py')])
+tested_examples = set([method[5:] for method in dir(self) if 
method.startswith('test_') and method != 'test_runs_everything'])
+
+extra = sorted(tested_examples.difference(all_examples))
+missing = sorted(all_examples.difference(tested_examples))
+
+if extra:
+  self.fail("Changed our examples directory? We test the following which 
are not present: %s" % ', '.join(extra))
+
+if missing:
+  self.fail("Changed our examples directory? The following are untested: 
%s" % ', '.join(missing))
+
+  def test_bandwidth_stats(self):
+pass
+
+  def test_benchmark_server_descriptor_stem(self):
+pass
+
+  def test_benchmark_stem(self):
+pass
+
+  def test_broken_listener(self):
+pass
+
+  def test_check_digests(self):
+pass
+
+  def test_client_usage_using_pycurl(self):
+pass
+
+  def test_client_usage_using_socksipy(self):
+pass
+
+  def test_collector_caching(self):
+pass
+
+  def test_collector_reading(self):
+pass
+
+  def test_compare_flags(self):
+pass
+
+  def test_create_descriptor(self):
+pass
+
+  def test_create_descriptor_content(self):
+pass
+
+  def test_current_descriptors(self):
+pass
+
+  def test_custom_path_selection(self):
+pass
+
+  def test_descriptor_from_orport(self):
+pass
+
+  def test_descriptor_from_tor_control_socket(self):
+pass
+
+  def test_descriptor_from_tor_data_directory(self):
+pass
+
+  def test_download_descriptor(self):
+pass
+
+  def test_ephemeral_hidden_services(self):
+pass
+
+  def test_event_listening(self):
+pass
+
+  def test_exit_used(self):
+pass
+
+  def test_fibonacci_multiprocessing(self):
+pass
+
+  def test_fibonacci_threaded(self):
+pass
+
+  def test_get_hidden_service_descriptor(self):
+pass
+
+  def test_hello_world(self):
+pass
+
+  def test_introduction_points(self):
+pass
+
+  def test_list_circuits(self):
+pass
+
+  def test_load_test(self):
+pass
+
+  def test_manual_config_options(self):
+pass
+
+  def test_outdated_relays(self):
+pass
+
+  def test_persisting_a_consensus(self):
+pass
+
+  def test_persisting_a_consensus_with_parse_file(self):
+pass
+
+  def test_queue_listener(self):
+pass
+
+  def test_read_with_parse_file(self):
+pass
+
+  def test_reading_twitter(self):
+pass
+
+  def test_relay_connections(self):
+pass
+
+  def test_resuming_ephemeral_hidden_service(self):
+pass
+
+  def test_running_hidden_service(self):
+pass
+
+  def test_saving_and_loading_descriptors(self):
+pass
+
+  def test_slow_listener(self):
+pass
+
+  def test_tor_descriptors(self):
+pass
+
+  def test_utilities(self):
+pass
+
+  def test_validate_descriptor_content(self):
+pass
+
+  def test_votes_by_bandwidth_authorities(self):
+  

[tor-commits] [stem/master] Test collector_caching example

2020-10-02 Thread atagar
commit 4bfaa5b7cdba1a533f7241a28e0e4286e1be081e
Author: Damian Johnson 
Date:   Sat Sep 26 15:14:57 2020 -0700

Test collector_caching example
---
 test/unit/examples.py | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 521a7937..7c801ece 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -19,6 +19,7 @@ from stem.descriptor.bandwidth_file import BandwidthFile
 from stem.descriptor.extrainfo_descriptor import RelayExtraInfoDescriptor
 from stem.descriptor.router_status_entry import RouterStatusEntryV3
 from stem.descriptor.server_descriptor import RelayDescriptor
+from stem.exit_policy import ExitPolicy
 from stem.response import ControlMessage
 from unittest.mock import Mock, patch
 
@@ -97,6 +98,12 @@ EXPECTED_COLLECTOR_CACHING = """\
   flubber (5C2124E6C5DD75C3C17C03EEA5A51812773DE671)
 """
 
+EXPECTED_COLLECTOR_READING = """\
+1 relays published an exiting policy today...
+
+  caerSidi (4F0C867DF0EF68160568C826838F482CEA7CFE44)
+"""
+
 
 class TestExamples(unittest.TestCase):
   def setUp(self):
@@ -256,8 +263,19 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual(EXPECTED_COLLECTOR_CACHING, stdout_mock.getvalue())
 
-  def test_collector_reading(self):
-pass
+  @patch('stem.descriptor.collector.CollecTor.get_server_descriptors')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_collector_reading(self, stdout_mock, server_desc_mock):
+server_desc_mock.return_value = [
+  RelayDescriptor.create({
+'router': 'caerSidi 71.35.133.197 9001 0 0',
+'fingerprint': '4F0C 867D F0EF 6816 0568 C826 838F 482C EA7C FE44',
+  }, exit_policy = ExitPolicy('accept *:*')),
+]
+
+import collector_reading
+
+self.assertEqual(EXPECTED_COLLECTOR_READING, stdout_mock.getvalue())
 
   def test_compare_flags(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Test check_digests example

2020-10-02 Thread atagar
commit 941c408c3a5c608e8272e629c61387f80ff1e2d4
Author: Damian Johnson 
Date:   Tue Sep 22 18:42:15 2020 -0700

Test check_digests example

Yay! Caught our second example bug, this time a minor python 3 error with
regard to iterating over a filter object.
---
 docs/_static/example/check_digests.py | 11 +--
 test/unit/examples.py | 54 ++-
 2 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/docs/_static/example/check_digests.py 
b/docs/_static/example/check_digests.py
index 69f509cf..93b037c0 100644
--- a/docs/_static/example/check_digests.py
+++ b/docs/_static/example/check_digests.py
@@ -16,7 +16,7 @@ def download_descriptors(fingerprint):
   server_desc_query = 
stem.descriptor.remote.get_server_descriptors(fingerprint)
   extrainfo_query = 
stem.descriptor.remote.get_extrainfo_descriptors(fingerprint)
 
-  router_status_entries = filter(lambda desc: desc.fingerprint == fingerprint, 
conensus_query.run())
+  router_status_entries = list(filter(lambda desc: desc.fingerprint == 
fingerprint, conensus_query.run()))
 
   if len(router_status_entries) != 1:
 raise OSError("Unable to find relay '%s' in the consensus" % fingerprint)
@@ -27,8 +27,8 @@ def download_descriptors(fingerprint):
 extrainfo_query.run()[0],
   )
 
-if __name__ == '__main__':
-  fingerprint = raw_input("What relay fingerprint would you like to 
validate?\n")
+
+def validate_relay(fingerprint):
   print('')  # blank line
 
   if not stem.util.tor_tools.is_valid_fingerprint(fingerprint):
@@ -50,3 +50,8 @@ if __name__ == '__main__':
 print("Extrainfo descriptor digest is correct")
   else:
 print("Extrainfo descriptor digest invalid, expected %s but is %s" % 
(server_desc.extra_info_digest, extrainfo_desc.digest()))
+
+
+if __name__ == '__main__':
+  fingerprint = raw_input("What relay fingerprint would you like to 
validate?\n")
+  validate_relay(fingerprint)
diff --git a/test/unit/examples.py b/test/unit/examples.py
index 2f664fd3..ba75a98c 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -2,6 +2,8 @@
 Exercise the code in our examples directory.
 """
 
+import base64
+import binascii
 import importlib
 import io
 import os
@@ -11,9 +13,13 @@ import unittest
 import stem.socket
 import stem.util.system
 import test
+import test.require
 
 from stem.control import Controller
 from stem.descriptor.bandwidth_file import BandwidthFile
+from stem.descriptor.extrainfo_descriptor import RelayExtraInfoDescriptor
+from stem.descriptor.router_status_entry import RouterStatusEntryV3
+from stem.descriptor.server_descriptor import RelayDescriptor
 from stem.response import ControlMessage
 from unittest.mock import Mock, patch
 
@@ -69,6 +75,16 @@ Finished 
measure_fraction_relays_exit_80_microdescriptors('%s')
   Time per microdescriptor:
 """.rstrip()
 
+EXPECTED_CHECK_DIGESTS_OK = """
+Server descriptor digest is correct
+Extrainfo descriptor digest is correct
+"""
+
+EXPECTED_CHECK_DIGESTS_BAD = """
+Server descriptor digest invalid, expected 
A106452D87BD7B803B6CE916291ED368DC5BD091 but is %s
+Extrainfo descriptor digest is correct
+"""
+
 
 def import_example(module_name):
   """
@@ -174,8 +190,44 @@ class TestExamples(unittest.TestCase):
 
 self.assertEqual('start of broken_handler\n', stdout_mock.getvalue())
 
+  @test.require.cryptography
   def test_check_digests(self):
-pass
+def download_of(desc):
+  query = Mock()
+  query.run.return_value = [desc]
+  return Mock(return_value = query)
+
+module = import_example('check_digests')
+fingerprint = 'A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB'
+
+extrainfo_desc = RelayExtraInfoDescriptor.create()
+server_desc = RelayDescriptor.create({'extra-info-digest': 
extrainfo_desc.digest()}, sign = True)
+
+encoded_digest = 
base64.b64encode(binascii.unhexlify(server_desc.digest())).rstrip(b'=')
+
+consensus_desc = RouterStatusEntryV3.create({
+  'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s %s 2012-08-06 11:19:31 
71.35.150.29 9001 0' % encoded_digest.decode('utf-8'),
+})
+
+bad_consensus_desc = RouterStatusEntryV3.create({
+  'r': 'caerSidi p1aag7VwarGxqctS7/fS0y5FU+s oQZFLYe9e4A7bOkWKR7TaNxb0JE 
2012-08-06 11:19:31 71.35.150.29 9001 0',
+})
+
+with patch('stem.descriptor.remote.get_server_descriptors', 
download_of(server_desc)):
+  with patch('stem.descriptor.remote.get_extrainfo_descriptors', 
download_of(extrainfo_desc)):
+# correctly signed descriptors
+
+with patch('stem.descriptor.remote.get_consensus', 
download_of(consensus_desc)):
+  with patch('sys.stdout', new_callable = io.StringIO) as stdout_mock:
+module.validate_relay(fingerprint)
+self.assertEqual(EXPECTED_CHECK_DIGESTS_OK, stdout_mock.getvalue())
+
+# incorrect server descriptor digest
+
+with patch('stem.descriptor.remote.get_consensus', 
download_of(bad_consensus_desc)):
+  with 

[tor-commits] [stem/master] Drop extra benchmark download links

2020-10-02 Thread atagar
commit da24bb2d89cbb860ed946a658281bf9a110d4960
Author: Damian Johnson 
Date:   Mon Sep 21 16:50:10 2020 -0700

Drop extra benchmark download links

I recently added download links for our examples, but the benchmark scripts 
are
an exception. First, some of these links were broken. Second, we already
provide a link above which we display a *subset* of (since the scripts are
pretty long).
---
 docs/tutorials/mirror_mirror_on_the_wall.rst | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/docs/tutorials/mirror_mirror_on_the_wall.rst 
b/docs/tutorials/mirror_mirror_on_the_wall.rst
index 80ae1104..6b383141 100644
--- a/docs/tutorials/mirror_mirror_on_the_wall.rst
+++ b/docs/tutorials/mirror_mirror_on_the_wall.rst
@@ -407,7 +407,6 @@ Stem Example
 * `Stem Benchmark Script <../.../../_static/example/benchmark_stem.py>`_
 
 .. literalinclude:: /_static/example/benchmark_server_descriptor_stem.py
-   :caption: `[Download] 
<../_static/example/benchmark_server_descriptor_stem.py>`__
:language: python
 
 Metrics-lib Example
@@ -416,7 +415,6 @@ Metrics-lib Example
 * `Metrics-lib Benchmark Script 
<../.../../_static/example/benchmark_metrics_lib.java>`_
 
 .. literalinclude:: 
/_static/example/benchmark_server_descriptor_metrics_lib.java
-   :caption: `[Download] 
<../_static/example/benchmark_server_descriptor_metrics_lib.py>`__
:language: java
 
 Zoossh Example
@@ -425,5 +423,4 @@ Zoossh Example
 * `Zoossh Benchmark Script <../.../../_static/example/benchmark_zoossh.go>`_
 
 .. literalinclude:: /_static/example/benchmark_server_descriptor_zoossh.go
-   :caption: `[Download] 
<../_static/example/benchmark_server_descriptor_zoossh.py>`__
:language: go



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move list_circuits test

2020-10-02 Thread atagar
commit faa569fcbe8a8d5bb1014c2961478a33465d113e
Author: Damian Johnson 
Date:   Sat Sep 26 18:08:45 2020 -0700

Move list_circuits test

Yikes. We have *three* test modules for our website examples...

  * tutorial.py, made in 2012
  * tutorial_examples.py, made in 2014
  * examples.py, from this branch

I've worked on Stem for so long clearly even I can't keep all our tests
straight. These modules cover a subset of our tutorial examples, so 
beginning
to merge them into examples.py. Unlike them, examples.py checks for new 
example
scripts so we'll finally stop re-inventing this wheel.
---
 docs/_static/example/list_circuits.py |  6 ++--
 stem/response/events.py   |  4 +++
 test/unit/examples.py | 58 +--
 test/unit/tutorial_examples.py| 49 -
 4 files changed, 63 insertions(+), 54 deletions(-)

diff --git a/docs/_static/example/list_circuits.py 
b/docs/_static/example/list_circuits.py
index b89e99fc..aff3b211 100644
--- a/docs/_static/example/list_circuits.py
+++ b/docs/_static/example/list_circuits.py
@@ -8,8 +8,8 @@ with Controller.from_port(port = 9051) as controller:
 if circ.status != CircStatus.BUILT:
   continue
 
-print("")
-print("Circuit %s (%s)" % (circ.id, circ.purpose))
+print('')
+print('Circuit %s (%s)' % (circ.id, circ.purpose))
 
 for i, entry in enumerate(circ.path):
   div = '+' if (i == len(circ.path) - 1) else '|'
@@ -18,4 +18,4 @@ with Controller.from_port(port = 9051) as controller:
   desc = controller.get_network_status(fingerprint, None)
   address = desc.address if desc else 'unknown'
 
-  print(" %s- %s (%s, %s)" % (div, fingerprint, nickname, address))
+  print(' %s- %s (%s, %s)' % (div, fingerprint, nickname, address))
diff --git a/stem/response/events.py b/stem/response/events.py
index 300d02d0..d9d46d6a 100644
--- a/stem/response/events.py
+++ b/stem/response/events.py
@@ -417,6 +417,10 @@ class CircuitEvent(Event):
 my_id = getattr(self, 'id')
 their_id = getattr(other, 'id')
 
+if my_id.isdigit() and their_id.isdigit():
+  my_id = int(my_id)
+  their_id = int(their_id)
+
 return method(my_id, their_id) if my_id != their_id else 
method(hash(self), hash(other))
 
   def __gt__(self, other: Any) -> bool:
diff --git a/test/unit/examples.py b/test/unit/examples.py
index 7c801ece..30375ea3 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -104,6 +104,24 @@ EXPECTED_COLLECTOR_READING = """\
   caerSidi (4F0C867DF0EF68160568C826838F482CEA7CFE44)
 """
 
+EXPECTED_LIST_CIRCUITS = """\
+
+Circuit 4 (GENERAL)
+ |- B1FA7D51B8B6F0CB585D944F450E7C06EDE7E44C (ByTORAndTheSnowDog, 
173.209.180.61)
+ |- 0DD9935C5E939CFA1E07B8DDA6D91C1A2A9D9338 (afo02, 87.238.194.176)
+ +- DB3B1CFBD3E4D97B84B548ADD5B9A31451EEC4CC (edwardsnowden3, 109.163.234.10)
+
+Circuit 6 (GENERAL)
+ |- B1FA7D51B8B6F0CB585D944F450E7C06EDE7E44C (ByTORAndTheSnowDog, 
173.209.180.61)
+ |- EC01CB4766BADC1611678555CE793F2A7EB2D723 (sprockets, 46.165.197.96)
+ +- 9EA317EECA56BDF30CAEB208A253FB456EDAB1A0 (bolobolo1, 96.47.226.20)
+
+Circuit 10 (GENERAL)
+ |- B1FA7D51B8B6F0CB585D944F450E7C06EDE7E44C (ByTORAndTheSnowDog, 
173.209.180.61)
+ |- 00C2C2A16AEDB51D5E5FB7D6168FC66B343D822F (ph3x, 86.59.119.83)
+ +- 65242C91BFF30F165DA4D132C81A9EBA94B71D62 (torexit16, 176.67.169.171)
+"""
+
 
 class TestExamples(unittest.TestCase):
   def setUp(self):
@@ -328,8 +346,44 @@ class TestExamples(unittest.TestCase):
   def test_introduction_points(self):
 pass
 
-  def test_list_circuits(self):
-pass
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_list_circuits(self, stdout_mock, from_port_mock):
+def _get_circ_event(circ_id, hop1, hop2, hop3):
+  path = '$%s=%s,$%s=%s,$%s=%s' % (hop1[0], hop1[1], hop2[0], hop2[1], 
hop3[0], hop3[1])
+  content = '650 CIRC %i BUILT %s PURPOSE=GENERAL' % (circ_id, path)
+  return ControlMessage.from_str(content, 'EVENT', normalize = True)
+
+path_1 = ('B1FA7D51B8B6F0CB585D944F450E7C06EDE7E44C', 'ByTORAndTheSnowDog')
+path_2 = ('0DD9935C5E939CFA1E07B8DDA6D91C1A2A9D9338', 'afo02')
+path_3 = ('DB3B1CFBD3E4D97B84B548ADD5B9A31451EEC4CC', 'edwardsnowden3')
+path_4 = ('EC01CB4766BADC1611678555CE793F2A7EB2D723', 'sprockets')
+path_5 = ('9EA317EECA56BDF30CAEB208A253FB456EDAB1A0', 'bolobolo1')
+path_6 = ('00C2C2A16AEDB51D5E5FB7D6168FC66B343D822F', 'ph3x')
+path_7 = ('65242C91BFF30F165DA4D132C81A9EBA94B71D62', 'torexit16')
+
+circuit_4 = _get_circ_event(4, path_1, path_2, path_3)
+circuit_6 = _get_circ_event(6, path_1, path_4, path_5)
+circuit_10 = _get_circ_event(10, path_1, path_6, path_7)
+
+controller = from_port_mock().__enter__()
+controller.get_circuits.return_value = [circuit_4, circuit_6, circuit_10]
+
+r_line = 'caerSidi 

[tor-commits] [stem/master] Test collector_caching example

2020-10-02 Thread atagar
commit 085018b9bace37a9758d5a0fbe447086612a8e8a
Author: Damian Johnson 
Date:   Fri Sep 25 17:21:56 2020 -0700

Test collector_caching example

Ooph. Despite looking simple it took me a few hours to get these mocks 
right...
---
 test/unit/examples.py | 28 ++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/test/unit/examples.py b/test/unit/examples.py
index 566611c5..521a7937 100644
--- a/test/unit/examples.py
+++ b/test/unit/examples.py
@@ -91,6 +91,12 @@ Server descriptor digest invalid, expected 
A106452D87BD7B803B6CE916291ED368DC5BD
 Extrainfo descriptor digest is correct
 """
 
+EXPECTED_COLLECTOR_CACHING = """\
+  krypton (3E2F63E2356F52318B536A12B6445373808A5D6C)
+  dizum (7EA6EAD6FD83083C538F44038BBFA077587DD755)
+  flubber (5C2124E6C5DD75C3C17C03EEA5A51812773DE671)
+"""
+
 
 class TestExamples(unittest.TestCase):
   def setUp(self):
@@ -229,8 +235,26 @@ class TestExamples(unittest.TestCase):
 module.validate_relay(fingerprint)
 self.assertEqual(EXPECTED_CHECK_DIGESTS_BAD % 
server_desc.digest(), stdout_mock.getvalue())
 
-  def test_collector_caching(self):
-pass
+  @patch('stem.descriptor.collector.File.download', Mock())
+  @patch('stem.descriptor.collector.CollecTor.files')
+  @patch('sys.stdout', new_callable = io.StringIO)
+  def test_collector_caching(self, stdout_mock, files_mock):
+files_mock.return_value = [stem.descriptor.collector.File(
+ 
'archive/relay-descriptors/server-descriptors/server-descriptors-2005-12.tar',
+  ['server-descriptor 1.0'],
+  1348620,
+  '0RrqB5aMY46vTeEHYqnbPVFGZQi1auJkzyHyt0NNDcw=',
+  '2005-12-15 01:42',
+  '2005-12-17 11:06',
+  '2016-06-24 08:12',
+)]
+
+server_desc = list(stem.descriptor.parse_file(os.path.join(DESC_DIR, 
'collector', 'server-descriptors-2005-12-cropped.tar')))
+
+with patch('stem.descriptor.parse_file', Mock(return_value = server_desc)):
+  import collector_caching
+
+self.assertEqual(EXPECTED_COLLECTOR_CACHING, stdout_mock.getvalue())
 
   def test_collector_reading(self):
 pass



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] TODO note to expand Descriptor.create()

2020-10-02 Thread atagar
commit e2ef267c68e43de7fa9b9fd126192c037bd04a24
Author: Damian Johnson 
Date:   Sat Sep 26 15:11:25 2020 -0700

TODO note to expand Descriptor.create()

TODO note to expand our Descriptor's create() and content() methods. These 
were
originally private methods within our tests. I productionized and opened 
them
for Isis so BridgeDB could replace Lector.

We use descriptor content as their input arguments for a couple reasons...

  1. It's agnostic to the descriptor type, so all Descriptors can largely 
share
 a constructor.

  2. This was the input our tests originally wanted to make test descriptors
 from.

However, it makes creating descriptors cumbersome. For instance, if I
simply want to make a server descriptor with my nickname I need to run...

  RelayDescriptor.create({'router': 'caerSidi 71.35.133.197 9001 0 0'})

Wouldn't this be a lot better if it was simply the following?

  RelayDescriptor.create(nickname = 'caerSidi')

However, doing this is easier said than done. Doing so will require reverse
mapping attributes to line content (that is to say, convert 'nickname ='
into something like the above router line.

Oh well. Project for another time when I rethink our Descriptor APIs.
---
 stem/descriptor/__init__.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/stem/descriptor/__init__.py b/stem/descriptor/__init__.py
index 58a88d55..3f10bc57 100644
--- a/stem/descriptor/__init__.py
+++ b/stem/descriptor/__init__.py
@@ -921,6 +921,9 @@ class Descriptor(object):
   * **NotImplementedError** if not implemented for this descriptor type
 """
 
+# TODO: add support for creating descriptors with preset parameters (rather
+# than line content)
+
 return cls(cls.content(attr, exclude), validate = validate)  # type: ignore
 
   def type_annotation(self) -> 'stem.descriptor.TypeAnnotation':



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Add prometheus exporter to examples

2020-09-11 Thread atagar
commit ab835c1a2972a654af991d9690776b755a9450c1
Author: Damian Johnson 
Date:   Fri Sep 11 16:14:05 2020 -0700

Add prometheus exporter to examples

Neat Stem user that came up on https://github.com/torproject/stem/issues/74
---
 docs/tutorials/double_double_toil_and_trouble.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/docs/tutorials/double_double_toil_and_trouble.rst 
b/docs/tutorials/double_double_toil_and_trouble.rst
index b631d479..53608359 100644
--- a/docs/tutorials/double_double_toil_and_trouble.rst
+++ b/docs/tutorials/double_double_toil_and_trouble.rst
@@ -85,6 +85,7 @@ Applications
 `BWScanner `_  
 Measurements for the tor bandwidth authorities. 
Interesting example of txtorcon and stem being used together.
 `Bushel `_ 
 Command-line descriptor download tools
 `blockstack-tor `_   
 Tor integration for `Blockstack 
`_
+`Prometheus exporter `_
 
===
 ==
 
 Scripts

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Trailing whitespace broke 'ss' connection resolution

2020-09-11 Thread atagar
commit 8a00dcb0cd1bf00e6fc5ea315de555882a175683
Author: Damian Johnson 
Date:   Fri Sep 11 15:56:37 2020 -0700

Trailing whitespace broke 'ss' connection resolution

Some platforms append trailing whitespace to the output of the 'ss' command.
Caught thanks to toralf...

  https://github.com/torproject/stem/issues/46

Determined the problem by running the following against toralf's output...

  from stem.util.connection import Resolver, get_connections
  from unittest.mock import patch

  with open('ss-nptu.log') as ss_file:
ss_output = ss_file.read()

  with patch('stem.util.system.call') as call_mock:
call_mock.return_value = ss_output.split('\n')

print('parsed %i connections' % len(get_connections(Resolver.SS, 
process_pid = 2238, process_name = 'tor')))

Before:

  % python3.7 demo.py
  Traceback (most recent call last):
File "demo.py", line 12, in 
  print('parsed %i connections' % len(get_connections(Resolver.SS, 
process_pid = 2238, process_name = 'tor')))
File "/home/atagar/Desktop/stem/stem/util/connection.py", line 333, in 
get_connections
  raise OSError('No results found using: %s' % resolver_command)
  OSError: No results found using: ss -nptu

After:

  % python3.7 demo.py
  parsed 8114 connections
---
 docs/change_log.rst  |  4 
 stem/util/connection.py  |  2 +-
 test/settings.cfg|  1 +
 test/unit/util/connection.py | 19 +++
 4 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/docs/change_log.rst b/docs/change_log.rst
index 5a9a8928..cc830d6c 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -67,6 +67,10 @@ The following are only available within Stem's `git 
repository
 
   * *transport* lines within extrainfo descriptors failed to validate
 
+ * **Utilities**
+
+  * *ss* connection resolver failed on platforms that append whitespace 
(:ticket:`46`)
+
  * **Installation**
 
   * Migrated from distutil to setuptools
diff --git a/stem/util/connection.py b/stem/util/connection.py
index a83922f7..2198d526 100644
--- a/stem/util/connection.py
+++ b/stem/util/connection.py
@@ -126,7 +126,7 @@ RESOLVER_FILTER = {
   Resolver.NETSTAT_WINDOWS: 
'^\\s*{protocol}\\s+{local}\\s+{remote}\\s+ESTABLISHED\\s+{pid}\\s*$',
 
   # tcpESTAB  0  0   192.168.0.20:44415   
38.229.79.2:443users:(("tor",15843,9))
-  Resolver.SS: 
'^{protocol}\\s+ESTAB\\s+.*\\s+{local}\\s+{remote}\\s+users:\\(\\("{name}",(?:pid=)?{pid},(?:fd=)?[0-9]+\\)\\)$',
+  Resolver.SS: 
'^{protocol}\\s+ESTAB\\s+.*\\s+{local}\\s+{remote}\\s+users:\\(\\("{name}",(?:pid=)?{pid},(?:fd=)?[0-9]+\\)\\)\\s*$',
 
   # tor  3873  atagar  45u  IPv4  40994  0t0  TCP 
10.243.55.20:45724->194.154.227.109:9001 (ESTABLISHED)
   Resolver.LSOF: '^{name}\\s+{pid}\\s+.*\\s+{protocol}\\s+{local}->{remote} 
\\(ESTABLISHED\\)$',
diff --git a/test/settings.cfg b/test/settings.cfg
index e49835ea..b1d26d92 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -188,6 +188,7 @@ pycodestyle.ignore stem/descriptor/__init__.py => E402: 
import stem.descriptor.s
 pycodestyle.ignore stem/descriptor/__init__.py => E402: import 
stem.descriptor.tordnsel
 pycodestyle.ignore test/unit/util/connection.py => W291: _tor tor
15843   10 pipe 0x0 state:
 pycodestyle.ignore test/unit/util/connection.py => W291: _tor tor
15843   11 pipe 0x0 state:
+pycodestyle.ignore test/unit/util/connection.py => W291: tcpESTAB
 
 # False positives from pyflakes. These are mappings between the path and the
 # issue.
diff --git a/test/unit/util/connection.py b/test/unit/util/connection.py
index 575667b4..24020c55 100644
--- a/test/unit/util/connection.py
+++ b/test/unit/util/connection.py
@@ -64,6 +64,12 @@ tcpESTAB  0  0  127.0.0.1:22 
   127.0.0.1:56673
 tcpESTAB  0  0   192.168.0.1:4441538.229.79.2:443  
  users:(("tor",15843,9))
 """
 
+SS_WHITESPACE_OUTPUT = """\
+Netid  State  Recv-Q Send-Q Local Address:Port   Peer Address:Port
+tcpESTAB  0  0   192.168.0.1:44092  23.112.135.72:443  
  users:(("tor",15843,10))
+tcpESTAB  0  0   192.168.0.1:4441538.229.79.2:443  
  users:(("tor",15843,9))
+"""
+
 SS_IPV6_OUTPUT = """\
 Netid  State  Recv-Q Send-Q Local Address:Port   Peer 
Address:Port
 tcpESTAB  0  0  5.9.158.75:443
107.170.93.13:56159   users:(("tor",pid=25056,fd=997))
@@ -315,6 +321,19 @@ class TestConnection(unittest.TestCase):
 call_mock.side_effect = OSError('Unable to call ss')
 self.assertRaises(OSError, 

[tor-commits] [stem/master] Allow control connection to IPv6 addresses

2020-09-10 Thread atagar
commit 1087ebf6dadad2cc3ee81ad5ba8dc35e327cb665
Author: Damian Johnson 
Date:   Thu Sep 10 18:20:04 2020 -0700

Allow control connection to IPv6 addresses

Controller.from_port() improperly rejects IPv6 addresses as invalid...

  https://github.com/torproject/stem/issues/74

This expands a few other methods to allow IPv6 addresses as well.
---
 docs/change_log.rst | 1 +
 stem/connection.py  | 4 ++--
 stem/control.py | 8 
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/docs/change_log.rst b/docs/change_log.rst
index bbd13ef5..5a9a8928 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -61,6 +61,7 @@ The following are only available within Stem's `git repository
   * Socket based control connections often raised BrokenPipeError when closed
   * Added :func:`~stem.control.Controller.add_hidden_service_auth`, 
:func:`~stem.control.Controller.remove_hidden_service_auth`, and 
:func:`~stem.control.Controller.list_hidden_service_auth` to the 
:class:`~stem.control.Controller`
   * Incorrect filesystem encoding broke latin-1 cookie path (:ticket:`57`)
+  * Allow control connection to IPv6 addresses (:ticket:`74`)
 
  * **Descriptors**
 
diff --git a/stem/connection.py b/stem/connection.py
index f5f92464..68cfda45 100644
--- a/stem/connection.py
+++ b/stem/connection.py
@@ -357,8 +357,8 @@ async def connect_async(control_port: Tuple[str, Union[str, 
int]] = ('127.0.0.1'
   elif control_port:
 if len(control_port) != 2:
   raise ValueError('The control_port argument for connect() should be an 
(address, port) tuple.')
-elif not stem.util.connection.is_valid_ipv4_address(control_port[0]):
-  raise ValueError("'%s' isn't a vaid IPv4 address" % control_port[0])
+elif not stem.util.connection.is_valid_ipv4_address(control_port[0]) and 
not stem.util.connection.is_valid_ipv6_address(control_port[0]):
+  raise ValueError("'%s' isn't a vaid address" % control_port[0])
 elif control_port[1] != 'default' and not 
stem.util.connection.is_valid_port(control_port[1]):
   raise ValueError("'%s' isn't a valid port" % control_port[1])
 
diff --git a/stem/control.py b/stem/control.py
index a232f4db..9a387f55 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -1072,7 +1072,7 @@ class Controller(BaseController):
 
 import stem.connection
 
-if not stem.util.connection.is_valid_ipv4_address(address):
+if not stem.util.connection.is_valid_ipv4_address(address) and not 
stem.util.connection.is_valid_ipv6_address(address):
   raise ValueError('Invalid IP address: %s' % address)
 elif port != 'default' and not stem.util.connection.is_valid_port(port):
   raise ValueError('Invalid port: %s' % port)
@@ -2611,7 +2611,7 @@ class Controller(BaseController):
 
 if not stem.util.connection.is_valid_port(port):
   raise stem.ProtocolError('GETCONF provided an invalid 
HiddenServicePort port (%s): %s' % (port, content))
-elif not stem.util.connection.is_valid_ipv4_address(target_address):
+elif not stem.util.connection.is_valid_ipv4_address(target_address) 
and not stem.util.connection.is_valid_ipv6_address(target_address):
   raise stem.ProtocolError('GETCONF provided an invalid 
HiddenServicePort target address (%s): %s' % (target_address, content))
 elif not stem.util.connection.is_valid_port(target_port):
   raise stem.ProtocolError('GETCONF provided an invalid 
HiddenServicePort target port (%s): %s' % (target_port, content))
@@ -2722,8 +2722,8 @@ class Controller(BaseController):
 
 if not stem.util.connection.is_valid_port(port):
   raise ValueError("%s isn't a valid port number" % port)
-elif target_address and not 
stem.util.connection.is_valid_ipv4_address(target_address):
-  raise ValueError("%s isn't a valid IPv4 address" % target_address)
+elif target_address and not 
stem.util.connection.is_valid_ipv4_address(target_address) and not 
stem.util.connection.is_valid_ipv6_address(target_address):
+  raise ValueError("%s isn't a valid IP address" % target_address)
 elif target_port is not None and not 
stem.util.connection.is_valid_port(target_port):
   raise ValueError("%s isn't a valid port number" % target_port)
 elif auth_type not in (None, 'basic', 'stealth'):

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Check ONION_CLIENT_AUTH_ADD version

2020-09-08 Thread atagar
commit a87bd9a0e2e9fdcd1ddf211e7deefd9a08dd5b48
Author: Damian Johnson 
Date:   Tue Sep 8 15:06:26 2020 -0700

Check ONION_CLIENT_AUTH_ADD version

Methods for new tor features (and their associated tests) should check tor's
version. Caught thanks to asn.
---
 stem/control.py  |  3 +++
 stem/version.py  | 16 +---
 test/integ/control/controller.py |  2 ++
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/stem/control.py b/stem/control.py
index 5ee9782e..a232f4db 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -3115,6 +3115,9 @@ class Controller(BaseController):
 :raises: :class:`stem.ControllerError` if the call fails
 """
 
+if await self.get_version() < 
stem.version.Requirement.ONION_CLIENT_AUTH_ADD:
+  raise ValueError('ONION_CLIENT_AUTH_ADD requires tor %s or higher' % 
stem.version.Requirement.ONION_CLIENT_AUTH_ADD)
+
 request = 'ONION_CLIENT_AUTH_ADD %s %s:%s' % (service_id, key_type, 
private_key)
 
 if client_name:
diff --git a/stem/version.py b/stem/version.py
index cd2c3c39..6edf93ae 100644
--- a/stem/version.py
+++ b/stem/version.py
@@ -26,13 +26,14 @@ easily parsed and compared, for instance...
 
   Enumerations for the version requirements of features.
 
-  = ===
-  Requirement   Description
-  = ===
-  **DORMANT_MODE**  **DORMANT** and **ACTIVE** :data:`~stem.Signal`
-  **DROPTIMEOUTS**  **DROPTIMEOUTS** controller command
-  **HSFETCH_V3**HSFETCH for version 3 hidden services
-  = ===
+  === ===
+  Requirement Description
+  === ===
+  **DORMANT_MODE****DORMANT** and **ACTIVE** :data:`~stem.Signal`
+  **DROPTIMEOUTS****DROPTIMEOUTS** controller command
+  **HSFETCH_V3**  HSFETCH for version 3 hidden services
+  **ONION_CLIENT_AUTH_ADD**   **ONION_CLIENT_AUTH_ADD** controller command
+  === ===
 """
 
 import functools
@@ -221,4 +222,5 @@ Requirement = stem.util.enum.Enum(
   ('DORMANT_MODE', Version('0.4.0.1-alpha')),
   ('DROPTIMEOUTS', Version('0.4.5.0-alpha')),
   ('HSFETCH_V3', Version('0.4.1.1-alpha')),
+  ('ONION_CLIENT_AUTH_ADD', Version('0.4.3.1-alpha')),
 )
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index 6f5da0c4..553b1a4e 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -1627,6 +1627,7 @@ class TestController(unittest.TestCase):
 await controller.set_conf('OrPort', str(test.runner.ORPORT))
 
   @test.require.controller
+  @test.require.version(stem.version.Requirement.ONION_CLIENT_AUTH_ADD)
   @async_test
   async def test_hidden_service_auth(self):
 """
@@ -1665,6 +1666,7 @@ class TestController(unittest.TestCase):
   #   https://gitlab.torproject.org/tpo/core/tor/-/issues/40090
 
   @test.require.controller
+  @test.require.version(stem.version.Requirement.ONION_CLIENT_AUTH_ADD)
   @async_test
   async def test_hidden_service_auth_invalid(self):
 """

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Drop incorrect maintainer link

2020-09-07 Thread atagar
commit 5e4fb6c21e90dc9553b2d2d801ea98b3c190a78d
Author: Damian Johnson 
Date:   Mon Sep 7 18:08:17 2020 -0700

Drop incorrect maintainer link

This link is to the wrong person. Caught thanks to jg71.
---
 docs/download.rst | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/docs/download.rst b/docs/download.rst
index d7582894..8b528bbd 100644
--- a/docs/download.rst
+++ b/docs/download.rst
@@ -187,8 +187,7 @@ Download
.. image:: /_static/label/slackware.png
   :target: https://slackbuilds.org/repository/14.2/python/stem/
 
-   Package by `Markus `_ for
-   `Slackware `_.
+   Package by Markus for `Slackware `_.
 
* - .. image:: /_static/section/download/freebsd.png
   :target: http://www.freshports.org/security/py-stem/

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] Drop incorrect maintainer link

2020-09-07 Thread atagar
commit 58771d52db7a6989822635db0ca9a1bbc2f77d77
Author: Damian Johnson 
Date:   Mon Sep 7 18:07:17 2020 -0700

Drop incorrect maintainer link

This link is to the wrong person. Caught thanks to jg71.
---
 web/index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/web/index.html b/web/index.html
index 3c62121..a980f7c 100644
--- a/web/index.html
+++ b/web/index.html
@@ -445,7 +445,7 @@ sudo python setup.py install
   
 https://slackbuilds.org/repository/14.2/python/nyx/; 
id="slackware">
 https://slackbuilds.org/repository/14.2/python/nyx/; 
class="platform-title">Slackware
-Package maintained by https://docs.slackware.com/wiki:user:markush;>Markus for http://slackbuilds.org/howto/;>Slackware.
+Package maintained by Markus for http://slackbuilds.org/howto/;>Slackware.
   
 
   

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [nyx/master] File and signature documentation

2020-09-07 Thread atagar
commit 958542fb899e9d6476064de49262721c59fa244b
Author: Damian Johnson 
Date:   Mon Sep 7 15:12:02 2020 -0700

File and signature documentation

Nyx's website is based on Stem's. Porting over the following...

  https://gitweb.torproject.org/stem.git/commit/?id=0c558be
---
 web/images/download/file.png | Bin 0 -> 8278 bytes
 web/images/download/{osx.png => mac.png} | Bin
 web/images/download/source.txt   |   6 +++
 web/index.html   |  65 +--
 4 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/web/images/download/file.png b/web/images/download/file.png
new file mode 100644
index 000..2d6259e
Binary files /dev/null and b/web/images/download/file.png differ
diff --git a/web/images/download/osx.png b/web/images/download/mac.png
similarity index 100%
rename from web/images/download/osx.png
rename to web/images/download/mac.png
diff --git a/web/images/download/source.txt b/web/images/download/source.txt
index a223302..d0de9fd 100644
--- a/web/images/download/source.txt
+++ b/web/images/download/source.txt
@@ -52,6 +52,12 @@ Platform images in this folder originate from the 
following...
   License: GPL v2
   File: NuoveXT/128x128/apps/openbsd.png
 
+* File
+  Source: NuoveXT (http://nuovext.pwsp.net/)
+  Author: Alexandre Moore (http://sa-ki.deviantart.com/)
+  License: GPL v2
+  File: NuoveXT/128x128/mimetypes/gnome-mime-application-x-archive.png 
+
 * Git
   Source: https://en.wikipedia.org/wiki/File:Git-logo.svg
   Author: Jason Long
diff --git a/web/index.html b/web/index.html
index 1919796..3c62121 100644
--- a/web/index.html
+++ b/web/index.html
@@ -157,6 +157,37 @@
   
 
 
+
+  How do I validate the PGP signature?
+  
+Most download options are maintained by 
their operating system's community. Nyx's author only provides PyPI, 
File, and Source.
+Releases are https://en.wikipedia.org/wiki/Pretty_Good_Privacy;>PGP signed and can 
be validated with the https://www.atagar.com/pgp.html;>author's 
key...
+
+
+  https://gnupg.org/;>Install GPG if you don't 
already have it.
+  Download Nyx's latest release and 
signature.
+  Get the key of Nyx's author...
+% gpg --keyserver keyserver.ubuntu.com --recv-keys 
0x9ABBEEC6
+gpg: requesting key 9ABBEEC6 from hkp server keyserver.ubuntu.com
+gpg: key 9ABBEEC6: public key "Damian Johnson (www.atagar.com) 
" imported
+gpg: no ultimately trusted keys found
+gpg: Total number processed: 1
+gpg:   imported: 1  (RSA: 1)
+  
+  Validate the downloaded file with the signature...
+gpg --verify nyx-2.0.4.tar.gz.asc nyx-2.0.4.tar.gz
+gpg: Signature made Mon 06 Nov 2017 12:28:13 PM PST using RSA key ID 87F30690
+gpg: Good signature from "Damian Johnson (www.atagar.com) "
+gpg: aka "Damian Johnson "
+gpg: WARNING: This key is not certified with a trusted signature!
+gpg:  There is no indication that the signature belongs to the owner.
+Primary key fingerprint: 6827 8CC5 DD2D 1E85 C4E4  5AD9 0445 B7AB 9ABB EEC6
+ Subkey fingerprint: 2AE2 24F5 C424 990A E520  6C85 8884 04C1 87F3 
0690
+  
+
+  
+
+
 
   Are there any other user interfaces for Tor?
   
@@ -354,31 +385,30 @@ sudo python setup.py install
   
   Download
 
-  Nyx is available Mac OSX, Linux, and BSD but not 
Windows. Find your platform below to get started. For what's changed see 
our change log.
+  Nyx is available Mac OS, Linux, and BSD but not 
Windows. Find your platform below to get started. For what's changed see 
our change log.
 
   
 
   
 https://pypi.python.org/pypi/nyx/; id="pypi">
 https://pypi.python.org/pypi/nyx/; 
class="platform-title">Python Package Index
-Signed releases and instructions for both Python 2.x and 3.x. You 
can easily install from its https://pypi.python.org/packages/42/37/85890dae5680f36f5b1c964ad41674ebb8d1186383fbca58f82e76de734c/nyx-2.0.4.tar.gz;>tarball
 (https://pypi.python.org/packages/42/37/85890dae5680f36f5b1c964ad41674ebb8d1186383fbca58f82e76de734c/nyx-2.0.4.tar.gz.asc;>sig),
 or with pip...
+You can install our latest release from the Python Package Index 
(PyPI) with pip...
 
-% sudo easy_install pip
 % sudo pip install nyx
 
   
 
   
-https://formulae.brew.sh/formula/nyx; id="osx">
-https://formulae.brew.sh/formula/nyx;>Mac OSX
-On OSX you can easily install with both the pip command 
above and brew...
+https://formulae.brew.sh/formula/nyx; id="mac">
+https://formulae.brew.sh/formula/nyx;>Mac OS
+On Mac OS you can easily install with both the pip command 
above and brew...
 % brew install nyx
   
 
   
 http://packages.debian.org/sid/nyx; id="debian">
  

  1   2   3   4   5   6   7   8   9   10   >