tor-commits
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 214853 discussions
[translation/vidalia_help] Update translations for vidalia_help
by translation@torproject.org 14 Nov '11
by translation@torproject.org 14 Nov '11
14 Nov '11
commit ea5151ad070047d5589a5e247dacc144215887c0
Author: Translation commit bot <translation(a)torproject.org>
Date: Mon Nov 14 08:45:21 2011 +0000
Update translations for vidalia_help
---
de/services.po | 17 ++++++++++++++---
1 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/de/services.po b/de/services.po
index 134488c..47ed8e3 100644
--- a/de/services.po
+++ b/de/services.po
@@ -2,13 +2,14 @@
# Translators:
# bastik <bastik.tor(a)googlemail.com>, 2011.
# runasand <runa.sandvik(a)gmail.com>, 2011.
+# <sebastian(a)urbach.org>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
"POT-Creation-Date: 2010-06-26 17:00+0200\n"
-"PO-Revision-Date: 2011-04-16 20:48+0000\n"
-"Last-Translator: bastik <bastik.tor(a)googlemail.com>\n"
+"PO-Revision-Date: 2011-11-14 08:44+0000\n"
+"Last-Translator: freedompenguin <sebastian(a)urbach.org>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -51,6 +52,10 @@ msgid ""
"provide a hidden service is built on top of the same circuits that Tor uses "
"for anonymous browsing and roughly has similar anonymity properties."
msgstr ""
+"Die Option versteckte Dienste bietet die Möglichkeit beliebige TCP-basierte "
+"Dienste anzubieten ohne die eigene IP-Adresse zu veröffentlichen. Das "
+"Protokoll für diese Dienste ist auf dem TOR-Protokoll aufgebaut das zum "
+"anonymen browsen verwendet wird und hat ungefähr die gleichen Eigenschaften."
#. type: Content of: <html><body><p>
#: en/services.html:35
@@ -59,11 +64,14 @@ msgid ""
"Tor's design paper (doc/design-paper/tor-design.pdf) or the Rendezvous "
"Specification (doc/spec/rend-spec.txt)."
msgstr ""
+"Um mehr Informationen zu den Hidden Services zu bekommen sollten Sie Sektion"
+" 5 des Tor Design Papiers lesen (doc/design-paper/tor-design.pdf) oder das "
+"Papier zum Thema Redenzvous Spezifikationen "
#. type: Content of: <html><body>
#: en/services.html:40
msgid "<a name=\"provide\"/>"
-msgstr ""
+msgstr "<a name=\"provide\"/>"
#. type: Content of: <html><body><h3>
#: en/services.html:41
@@ -83,6 +91,9 @@ msgid ""
"Install a web server locally (or a server for whatever service you want to "
"provide, e.g. IRC) to listen for local requests."
msgstr ""
+"Installieren Sie einen lokalen Web-Server (oder einen Server für den "
+"entsprechenden Service den Sie anbieten wollen wie z.B. IRC) der auf lokale "
+"Verbindungen wartet."
#. type: Content of: <html><body><p><ol><li>
#: en/services.html:47
1
0
14 Nov '11
commit f27c2d76c13858456c0f9b5f05532aedce28303b
Author: Translation commit bot <translation(a)torproject.org>
Date: Mon Nov 14 04:15:11 2011 +0000
Update translations for gettor
---
ar/gettor.po | 18 +++++++++++++++---
cy/gettor.po | 18 +++++++++++++++---
da/gettor.po | 20 +++++++++++++++-----
de/gettor.po | 20 +++++++++++++++-----
el/gettor.po | 18 +++++++++++++++---
es/gettor.po | 21 +++++++++++++++------
fa/gettor.po | 18 +++++++++++++++---
fr/gettor.po | 21 +++++++++++++++------
hu/gettor.po | 20 +++++++++++++++-----
it/gettor.po | 18 +++++++++++++++---
nl/gettor.po | 21 +++++++++++++++------
pl/gettor.po | 20 +++++++++++++++-----
ru/gettor.po | 16 ++++++++++++++--
templates/gettor.pot | 25 ++++++++++++++++++++++---
14 files changed, 216 insertions(+), 58 deletions(-)
diff --git a/ar/gettor.po b/ar/gettor.po
index 7b921b2..a7122a7 100644
--- a/ar/gettor.po
+++ b/ar/gettor.po
@@ -11,8 +11,8 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
-"PO-Revision-Date: 2011-10-20 18:07+0000\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
+"PO-Revision-Date: 2011-11-14 04:06+0000\n"
"Last-Translator: redeemer <fadi.redeemer.mansour(a)gmail.com>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
"MIME-Version: 1.0\n"
@@ -61,7 +61,7 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
#: lib/gettor/i18n.py:46
@@ -548,4 +548,16 @@ msgstr ""
msgid "ANSWER:"
msgstr ""
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/cy/gettor.po b/cy/gettor.po
index d591e25..eb4c327 100644
--- a/cy/gettor.po
+++ b/cy/gettor.po
@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
-"PO-Revision-Date: 2011-09-11 00:43+0000\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
+"PO-Revision-Date: 2011-11-14 04:06+0000\n"
"Last-Translator: cymro <markives(a)hotmail.co.uk>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
"MIME-Version: 1.0\n"
@@ -50,7 +50,7 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
#: lib/gettor/i18n.py:46
@@ -441,4 +441,16 @@ msgstr ""
msgid "ANSWER:"
msgstr ""
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/da/gettor.po b/da/gettor.po
index 288b505..1e6f902 100644
--- a/da/gettor.po
+++ b/da/gettor.po
@@ -10,8 +10,8 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
-"PO-Revision-Date: 2011-10-09 22:37+0000\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
+"PO-Revision-Date: 2011-11-14 04:06+0000\n"
"Last-Translator: OliverMller <theoliver(a)live.co.uk>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
"MIME-Version: 1.0\n"
@@ -60,10 +60,8 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
-"Hvis du har spørgsmål, eller det ikke virker, kan du kontakte en person på "
-"denne støtte e-mail-adresse: community-support(a)lists.torproject.org"
#: lib/gettor/i18n.py:46
msgid ""
@@ -617,4 +615,16 @@ msgstr "SPØRGSMÅL:"
msgid "ANSWER:"
msgstr "SVAR:"
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/de/gettor.po b/de/gettor.po
index b724046..3871b1e 100644
--- a/de/gettor.po
+++ b/de/gettor.po
@@ -11,8 +11,8 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
-"PO-Revision-Date: 2011-09-21 14:37+0000\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
+"PO-Revision-Date: 2011-11-14 04:06+0000\n"
"Last-Translator: cyberfork <benni(a)include-benni.de>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
"MIME-Version: 1.0\n"
@@ -60,10 +60,8 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
-"Solltest du fragen haben oder etwas nicht funktionieren kannst du hier über "
-"die Email Adresse community-support(a)lists.torproject.org Support anfordern."
#: lib/gettor/i18n.py:46
msgid ""
@@ -595,4 +593,16 @@ msgstr "FRAGE:"
msgid "ANSWER:"
msgstr "ANTWORT:"
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/el/gettor.po b/el/gettor.po
index 7a72a2b..cbd9636 100644
--- a/el/gettor.po
+++ b/el/gettor.po
@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
-"PO-Revision-Date: 2011-10-23 13:48+0000\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
+"PO-Revision-Date: 2011-11-14 04:06+0000\n"
"Last-Translator: anestv <varsamidis7-etc(a)yahoo.gr>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
"MIME-Version: 1.0\n"
@@ -54,7 +54,7 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
#: lib/gettor/i18n.py:46
@@ -463,4 +463,16 @@ msgstr ""
msgid "ANSWER:"
msgstr ""
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/es/gettor.po b/es/gettor.po
index 83d75df..059ac8d 100644
--- a/es/gettor.po
+++ b/es/gettor.po
@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
-"PO-Revision-Date: 2011-10-20 05:47+0000\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
+"PO-Revision-Date: 2011-11-14 04:06+0000\n"
"Last-Translator: lenazun <lenazun(a)gmail.com>\n"
"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/torproject/team/es/)\n"
"MIME-Version: 1.0\n"
@@ -60,11 +60,8 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
-"Si tiene alguna pregunta o el sistema no funciona, puede ponerse en contacto"
-" con una persona en esta dirección de correo de soporte: community-"
-"support(a)lists.torproject.org"
#: lib/gettor/i18n.py:46
msgid ""
@@ -597,4 +594,16 @@ msgstr "PREGUNTA:"
msgid "ANSWER:"
msgstr "RESPUESTA:"
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/fa/gettor.po b/fa/gettor.po
index 1d4dd15..035e4de 100644
--- a/fa/gettor.po
+++ b/fa/gettor.po
@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
-"PO-Revision-Date: 2011-09-11 00:43+0000\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
+"PO-Revision-Date: 2011-11-14 04:06+0000\n"
"Last-Translator: behravan <behravanhamed(a)gmail.com>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
"MIME-Version: 1.0\n"
@@ -57,7 +57,7 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
#: lib/gettor/i18n.py:46
@@ -484,4 +484,16 @@ msgstr ""
msgid "ANSWER:"
msgstr ""
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/fr/gettor.po b/fr/gettor.po
index 8ead25f..bb4ea67 100644
--- a/fr/gettor.po
+++ b/fr/gettor.po
@@ -12,8 +12,8 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
-"PO-Revision-Date: 2011-10-26 20:03+0000\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
+"PO-Revision-Date: 2011-11-14 04:06+0000\n"
"Last-Translator: arpalord <arpalord(a)gmail.com>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
"MIME-Version: 1.0\n"
@@ -64,11 +64,8 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
-"Si vous avez des questions ou qu'il ne fonctionne pas, vous pouvez joindre "
-"un humain à cette adresse email du support: community-"
-"support(a)lists.torproject.org"
#: lib/gettor/i18n.py:46
msgid ""
@@ -606,4 +603,16 @@ msgstr "QUESTION:"
msgid "ANSWER:"
msgstr "REPONSE:"
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/hu/gettor.po b/hu/gettor.po
index 713c784..59bd70f 100644
--- a/hu/gettor.po
+++ b/hu/gettor.po
@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
-"PO-Revision-Date: 2011-10-01 10:41+0000\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
+"PO-Revision-Date: 2011-11-14 04:06+0000\n"
"Last-Translator: vargaviktor <viktor.varga(a)gmail.com>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
"MIME-Version: 1.0\n"
@@ -59,10 +59,8 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
-"Ha kérdése van vagy nem működik, elérhet egy embert ezen az email címen: "
-"community-support(a)lists.torproject.org"
#: lib/gettor/i18n.py:46
msgid ""
@@ -592,4 +590,16 @@ msgstr "KÉRDÉS:"
msgid "ANSWER:"
msgstr "VÁLASZ:"
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/it/gettor.po b/it/gettor.po
index 618b1b5..e465588 100644
--- a/it/gettor.po
+++ b/it/gettor.po
@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
-"PO-Revision-Date: 2011-10-10 15:59+0000\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
+"PO-Revision-Date: 2011-11-14 04:06+0000\n"
"Last-Translator: jeckodevelopment <luca(a)jeckodevelopment.it>\n"
"Language-Team: Italian (http://www.transifex.net/projects/p/torproject/team/it/)\n"
"MIME-Version: 1.0\n"
@@ -57,7 +57,7 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
#: lib/gettor/i18n.py:46
@@ -459,4 +459,16 @@ msgstr ""
msgid "ANSWER:"
msgstr ""
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/nl/gettor.po b/nl/gettor.po
index 839ee3b..fdd6a85 100644
--- a/nl/gettor.po
+++ b/nl/gettor.po
@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
-"PO-Revision-Date: 2011-10-12 22:43+0000\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
+"PO-Revision-Date: 2011-11-14 04:06+0000\n"
"Last-Translator: Shondoit <shondoit+transifex(a)gmail.com>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
"MIME-Version: 1.0\n"
@@ -61,11 +61,8 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
-"Als je een vraag hebt of het werkt niet, dan kan je in contact komen met een"
-" mens bij dit ondersteunings-e-mailadres: community-"
-"support(a)lists.torproject.org"
#: lib/gettor/i18n.py:46
msgid ""
@@ -595,4 +592,16 @@ msgstr "VRAAG:"
msgid "ANSWER:"
msgstr "ANTWOORD:"
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/pl/gettor.po b/pl/gettor.po
index 72bf1a1..b697173 100644
--- a/pl/gettor.po
+++ b/pl/gettor.po
@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
-"PO-Revision-Date: 2011-09-11 10:59+0000\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
+"PO-Revision-Date: 2011-11-14 04:06+0000\n"
"Last-Translator: bogdrozd <bog.d(a)gazeta.pl>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
"MIME-Version: 1.0\n"
@@ -60,10 +60,8 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
-"Jeśli masz pytania lub to nie działa, możesz skontaktować się z\n"
-"człowiekiem pod tym adresem: community-support(a)lists.torproject.org"
#: lib/gettor/i18n.py:46
msgid ""
@@ -601,4 +599,16 @@ msgstr "PYTANIE:"
msgid "ANSWER:"
msgstr "ODPOWIEDŹ:"
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/ru/gettor.po b/ru/gettor.po
index cd59b08..2ac98d0 100644
--- a/ru/gettor.po
+++ b/ru/gettor.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
"PO-Revision-Date: 2010-11-30 05:01+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Russian (http://www.transifex.net/projects/p/torproject/team/ru/)\n"
@@ -50,7 +50,7 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
#: lib/gettor/i18n.py:46
@@ -441,4 +441,16 @@ msgstr ""
msgid "ANSWER:"
msgstr ""
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+
diff --git a/templates/gettor.pot b/templates/gettor.pot
index 32a72c6..282e40c 100644
--- a/templates/gettor.pot
+++ b/templates/gettor.pot
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: The Tor Project\n"
"Report-Msgid-Bugs-To: https://trac.torproject.org/projects/tor\n"
-"POT-Creation-Date: 2011-09-10 01:52-0400\n"
+"POT-Creation-Date: 2011-11-13 22:01+0100\n"
"PO-Revision-Date: 2010-11-30 05:01+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
@@ -58,10 +58,10 @@ msgstr ""
#: lib/gettor/i18n.py:43 lib/gettor/i18n.py:130
msgid ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
msgstr ""
"If you have any questions or it doesn't work, you can contact a\n"
-"human at this support email address: community-support(a)lists.torproject.org"
+"human at this support email address: help(a)rt.torproject.org"
#: lib/gettor/i18n.py:46
msgid ""
@@ -606,4 +606,23 @@ msgstr "QUESTION:"
msgid "ANSWER:"
msgstr "ANSWER:"
+#: lib/gettor/i18n.py:274
+#, python-format
+msgid ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+msgstr ""
+"Sorry, but the package you requested (%s) is too large for your \n"
+"provider to accept as an attachment. Try using another provider that allows \n"
+"for larger email attachments. Or try one of the following mirrors:\n"
+"\n"
+" https://www.oignon.net/dist/torbrowser/\n"
+" https://tor.beme-it.de/dist/torbrowser/\n"
+" https://www.torservers.net/mirrors/torproject.org/dist/torbrowser/"
+
1
0
[stem/master] Header documentation for the proc and system utils
by atagar@torproject.org 14 Nov '11
by atagar@torproject.org 14 Nov '11
14 Nov '11
commit dbe041ac1bbb775f71f34f0d705d4dd654d74858
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sun Nov 13 16:21:09 2011 -0800
Header documentation for the proc and system utils
---
stem/util/proc.py | 9 +++++++++
stem/util/system.py | 9 +++++++++
2 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/stem/util/proc.py b/stem/util/proc.py
index 79cf92a..32ab920 100644
--- a/stem/util/proc.py
+++ b/stem/util/proc.py
@@ -11,6 +11,15 @@ https://code.google.com/p/psutil/
which was written by Jay Loden, Dave Daeschler, Giampaolo Rodola' and is under
the BSD license.
+
+is_available - checks if proc utilities can be used on this system
+get_system_start_time - unix timestamp for when the system started
+get_physical_memory - memory available on this system
+get_cwd - provides the current working directory for a process
+get_uid - provides the user id a process is running under
+get_memory_usage - provides the memory usage of a process
+get_stats - queries statistics about a process
+get_connections - provides the connections made by a process
"""
import os
diff --git a/stem/util/system.py b/stem/util/system.py
index fd7277d..e5ba367 100644
--- a/stem/util/system.py
+++ b/stem/util/system.py
@@ -1,6 +1,15 @@
"""
Helper functions for working with the underlying system. These are mostly os
dependent, only working on linux, osx, and bsd.
+
+is_available - determines if a command is availabe on this system
+is_running - determines if a given process is running
+get_pid - provides the process id a given process is running under
+get_cwd - provides the current working directory for a given process
+get_bsd_jail_id - provides the BSD jail id a given process is running within
+is_relative_path - checks if a given path can be expanded by expand_path
+expand_path - expands relative paths and ~ entries
+call - runs the given system command and provides back the results
"""
import re
1
0
commit 382bc5627b8d4f29645207628ca224f08f7b6883
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sun Nov 13 16:13:33 2011 -0800
Basic integ test for stem.util.conf
Adding an integ test for the example given by the conf utility. There's a whole
lot more that could be tested in that class (especially parsing and type
inferences) but this doesn't seem too worth while so just adding this basic
test for now. I might expand it later.
---
run_tests.py | 2 +
test/integ/util/conf.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/run_tests.py b/run_tests.py
index 7dcffaf..774c130 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -18,6 +18,7 @@ import test.unit.types.version
import test.unit.connection.protocolinfo_response
import test.unit.util.enum
import test.integ.types.control_message
+import test.integ.util.conf
import test.integ.util.system
import stem.util.enum
@@ -36,6 +37,7 @@ UNIT_TESTS = (("stem.types.ControlMessage", test.unit.types.control_message.Test
)
INTEG_TESTS = (("stem.types.ControlMessage", test.integ.types.control_message.TestControlMessage),
+ ("stem.util.conf", test.integ.util.conf.TestConf),
("stem.util.system", test.integ.util.system.TestSystem),
)
diff --git a/test/integ/util/conf.py b/test/integ/util/conf.py
new file mode 100644
index 0000000..03ac4a1
--- /dev/null
+++ b/test/integ/util/conf.py
@@ -0,0 +1,54 @@
+"""
+Integration tests for the stem.util.conf class and functions.
+"""
+
+import os
+import tempfile
+import unittest
+
+import stem.util.conf
+
+CONF_PATH = tempfile.mktemp("-conf-test")
+CONF_HEADER = """# Demo configuration for integration tests to run against. Nothing to see here,
+# move along, move along.
+"""
+
+EXAMPLE_CONF = """%s
+destination.ip 1.2.3.4
+destination.port blarg
+
+startup.run export PATH=$PATH:~/bin
+startup.run alias l=ls
+""" % CONF_HEADER
+
+class TestConf(unittest.TestCase):
+ def tearDown(self):
+ # cleans up test configurations we made
+ if os.path.exists(CONF_PATH):
+ os.remove(CONF_PATH)
+
+ def test_example(self):
+ """
+ Checks that the pydoc example is correct.
+ """
+
+ test_conf_file = open(CONF_PATH, "w")
+ test_conf_file.write(EXAMPLE_CONF)
+ test_conf_file.close()
+
+ ssh_config = {"login.user": "atagar",
+ "login.password": "pepperjack_is_awesome!",
+ "destination.ip": "127.0.0.1",
+ "destination.port": 22,
+ "startup.run": []}
+
+ user_config = stem.util.conf.get_config("integ-ssh_login")
+ user_config.load(CONF_PATH)
+ user_config.update(ssh_config)
+
+ self.assertEquals("atagar", ssh_config["login.user"])
+ self.assertEquals("pepperjack_is_awesome!", ssh_config["login.password"])
+ self.assertEquals("1.2.3.4", ssh_config["destination.ip"])
+ self.assertEquals(22, ssh_config["destination.port"])
+ self.assertEquals(["export PATH=$PATH:~/bin", "alias l=ls"], ssh_config["startup.run"])
+
1
0
commit db7635abc7878d873a989c35e7aea413ecde2f52
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sun Nov 13 14:38:56 2011 -0800
Revising enum docs and methods
Minor changes including...
- standard header documentation
- replacing the keys() method with making enums iterable (functionally the
same, but a little nicer for callers)
- dropping the alternative LEnum - I've never used it
---
stem/util/enum.py | 39 +++++++++++++++------------------------
1 files changed, 15 insertions(+), 24 deletions(-)
diff --git a/stem/util/enum.py b/stem/util/enum.py
index d7745ec..6ce54d0 100644
--- a/stem/util/enum.py
+++ b/stem/util/enum.py
@@ -5,7 +5,7 @@ constructed as simple type listings, ie:
>>> insects.ANT
'Ant'
>>> insects.values()
-['Ant', 'Wasp', 'Ladybug', 'Firefly']
+('Ant', 'Wasp', 'Ladybug', 'Firefly')
with overwritten string counterparts:
>>> pets = Enum(("DOG", "Skippy"), "CAT", ("FISH", "Nemo"))
@@ -14,10 +14,13 @@ with overwritten string counterparts:
>>> pets.CAT
'Cat'
-or with entirely custom string components as an unordered enum with:
->>> pets = LEnum(DOG="Skippy", CAT="Kitty", FISH="Nemo")
->>> pets.CAT
-'Kitty'
+to_camel_case - converts a string to camel case
+Enum - Provides a basic, ordered enumeration.
+ |- values - string representation of our enums
+ |- index_of - indice of an enum value
+ |- next - provides the enum after a given enum value
+ |- previous - provides the enum before a given value
+ +- __iter__ - iterator over our enum keys
"""
def to_camel_case(label, word_divider = " "):
@@ -62,16 +65,6 @@ class Enum:
self._keys = tuple(keys)
self._values = tuple(values)
- def keys(self):
- """
- Provides an ordered listing of the enumeration keys in this set.
-
- Returns:
- tuple with our enum keys
- """
-
- return self._keys
-
def values(self):
"""
Provides an ordered listing of the enumerations in this set.
@@ -137,14 +130,12 @@ class Enum:
prev_index = (self._values.index(value) - 1) % len(self._values)
return self._values[prev_index]
-
-class LEnum(Enum):
- """
- Enumeration that accepts custom string mappings.
- """
- def __init__(self, **args):
- Enum.__init__(self)
- self.__dict__.update(args)
- self._values = sorted(args.values())
+ def __iter__(self):
+ """
+ Provides an ordered listing of the enumeration keys in this set.
+ """
+
+ for entry in self._keys:
+ yield entry
1
0
commit 2b797d0ba9310a015bef5bc2605020ebe8ffafdd
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sun Nov 13 13:15:49 2011 -0800
Unit tests for PROTOCOLINFO responses
---
run_tests.py | 2 +
stem/connection.py | 10 +-
test/unit/connection/__init__.py | 6 +
test/unit/connection/protocolinfo_response.py | 144 +++++++++++++++++++++++++
4 files changed, 158 insertions(+), 4 deletions(-)
diff --git a/run_tests.py b/run_tests.py
index 0b86706..1107a59 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -15,6 +15,7 @@ import test.runner
import test.unit.types.control_message
import test.unit.types.control_line
import test.unit.types.version
+import test.unit.connection.protocolinfo_response
import test.integ.message
import test.integ.system
@@ -29,6 +30,7 @@ DIVIDER = "=" * 70
UNIT_TESTS = (("stem.types.ControlMessage", test.unit.types.control_message.TestControlMessage),
("stem.types.ControlLine", test.unit.types.control_line.TestControlLine),
("stem.types.Version", test.unit.types.version.TestVerion),
+ ("stem.connection.ProtocolInfoResponse", test.unit.connection.protocolinfo_response.TestProtocolInfoResponse),
)
INTEG_TESTS = (("stem.types.ControlMessage", test.integ.message.TestMessageFunctions),
diff --git a/stem/connection.py b/stem/connection.py
index d17efde..2b96899 100644
--- a/stem/connection.py
+++ b/stem/connection.py
@@ -53,7 +53,8 @@ class ProtocolInfoResponse(stem.types.ControlMessage):
def convert(control_message):
"""
- Parses a ControlMessage, converting it into a ProtocolInfoResponse.
+ Parses a ControlMessage, performing an in-place conversion of it into a
+ ProtocolInfoResponse.
Arguments:
control_message (stem.types.ControlMessage) -
@@ -61,7 +62,7 @@ class ProtocolInfoResponse(stem.types.ControlMessage):
Raises:
stem.types.ProtocolError the message isn't a proper PROTOCOLINFO response
- ValueError if argument is of the wrong type
+ TypeError if argument isn't a ControlMessage
"""
if isinstance(control_message, stem.types.ControlMessage):
@@ -69,7 +70,7 @@ class ProtocolInfoResponse(stem.types.ControlMessage):
control_message._parse_message()
return control_message
else:
- raise ValueError("Only able to convert stem.types.ControlMessage instances")
+ raise TypeError("Only able to convert stem.types.ControlMessage instances")
convert = staticmethod(convert)
@@ -152,7 +153,7 @@ class ProtocolInfoResponse(stem.types.ControlMessage):
# parse optional COOKIEFILE mapping (quoted and can have escapes)
if line.is_next_mapping("COOKIEFILE", True, True):
- self.cookie_file = line.pop_mapping(True, True)[0]
+ self.cookie_file = line.pop_mapping(True, True)[1]
# attempt to expand relative cookie paths
if stem.util.system.is_relative_path(self.cookie_file):
@@ -286,6 +287,7 @@ class ControlConnection:
while self.is_running():
try:
+ # TODO: this raises a SocketClosed when... well, the socket is closed
control_message = stem.types.read_message(self._control_socket_file)
if control_message.content()[-1][0] == "650":
diff --git a/test/unit/connection/__init__.py b/test/unit/connection/__init__.py
new file mode 100644
index 0000000..440773e
--- /dev/null
+++ b/test/unit/connection/__init__.py
@@ -0,0 +1,6 @@
+"""
+Unit tests for stem.connection.
+"""
+
+__all__ = ["protocolinfo_response"]
+
diff --git a/test/unit/connection/protocolinfo_response.py b/test/unit/connection/protocolinfo_response.py
new file mode 100644
index 0000000..0dcde95
--- /dev/null
+++ b/test/unit/connection/protocolinfo_response.py
@@ -0,0 +1,144 @@
+"""
+Unit tests for the stem.connection.ProtocolInfoResponse class.
+"""
+
+import unittest
+import StringIO
+import stem.connection
+import stem.types
+
+NO_AUTH = """250-PROTOCOLINFO 1
+250-AUTH METHODS=NULL
+250-VERSION Tor="0.2.1.30"
+250 OK
+""".replace("\n", "\r\n")
+
+PASSWORD_AUTH = """250-PROTOCOLINFO 1
+250-AUTH METHODS=HASHEDPASSWORD
+250-VERSION Tor="0.2.1.30"
+250 OK
+""".replace("\n", "\r\n")
+
+COOKIE_AUTH = r"""250-PROTOCOLINFO 1
+250-AUTH METHODS=COOKIE COOKIEFILE="/tmp/my data\\\"dir//control_auth_cookie"
+250-VERSION Tor="0.2.1.30"
+250 OK
+""".replace("\n", "\r\n")
+
+MULTIPLE_AUTH = """250-PROTOCOLINFO 1
+250-AUTH METHODS=COOKIE,HASHEDPASSWORD COOKIEFILE="/home/atagar/.tor/control_auth_cookie"
+250-VERSION Tor="0.2.1.30"
+250 OK
+""".replace("\n", "\r\n")
+
+UNKNOWN_AUTH = """250-PROTOCOLINFO 1
+250-AUTH METHODS=MAGIC,HASHEDPASSWORD,PIXIE_DUST
+250-VERSION Tor="0.2.1.30"
+250 OK
+""".replace("\n", "\r\n")
+
+MINIMUM_RESPONSE = """250-PROTOCOLINFO 5
+250 OK
+""".replace("\n", "\r\n")
+
+class TestProtocolInfoResponse(unittest.TestCase):
+ """
+ Tests the parsing of ControlMessages for PROTOCOLINFO responses.
+ """
+
+ def test_convert(self):
+ """
+ Exercises functionality of the convert method both when it works and
+ there's an error.
+ """
+
+ # working case
+ control_message = stem.types.read_message(StringIO.StringIO(NO_AUTH))
+ stem.connection.ProtocolInfoResponse.convert(control_message)
+
+ # now this should be a ProtocolInfoResponse (ControlMessage subclass)
+ self.assertTrue(isinstance(control_message, stem.types.ControlMessage))
+ self.assertTrue(isinstance(control_message, stem.connection.ProtocolInfoResponse))
+
+ # exercise some of the ControlMessage functionality
+ self.assertTrue(str(control_message).startswith("PROTOCOLINFO 1"))
+ self.assertEquals(NO_AUTH, control_message.raw_content())
+
+ # attempt to convert the wrong type
+ self.assertRaises(TypeError, stem.connection.ProtocolInfoResponse.convert, "hello world")
+
+ # attempt to convert a different message type
+ bw_event_control_message = stem.types.read_message(StringIO.StringIO("650 BW 32326 2856\r\n"))
+ self.assertRaises(stem.types.ProtocolError, stem.connection.ProtocolInfoResponse.convert, bw_event_control_message)
+
+ def test_no_auth(self):
+ """
+ Checks a response when there's no authentication.
+ """
+
+ control_message = stem.types.read_message(StringIO.StringIO(NO_AUTH))
+ stem.connection.ProtocolInfoResponse.convert(control_message)
+
+ self.assertEquals(1, control_message.protocol_version)
+ self.assertEquals(stem.types.Version("0.2.1.30"), control_message.tor_version)
+ self.assertEquals((stem.connection.AuthMethod.NONE, ), control_message.auth_methods)
+ self.assertEquals((), control_message.unknown_auth_methods)
+ self.assertEquals(None, control_message.cookie_file)
+ self.assertEquals(None, control_message.socket)
+
+ def test_password_auth(self):
+ """
+ Checks a response with password authentication.
+ """
+
+ control_message = stem.types.read_message(StringIO.StringIO(PASSWORD_AUTH))
+ stem.connection.ProtocolInfoResponse.convert(control_message)
+ self.assertEquals((stem.connection.AuthMethod.PASSWORD, ), control_message.auth_methods)
+
+ def test_cookie_auth(self):
+ """
+ Checks a response with cookie authentication and a path including escape
+ characters.
+ """
+
+ control_message = stem.types.read_message(StringIO.StringIO(COOKIE_AUTH))
+ stem.connection.ProtocolInfoResponse.convert(control_message)
+ self.assertEquals((stem.connection.AuthMethod.COOKIE, ), control_message.auth_methods)
+ self.assertEquals("/tmp/my data\\\"dir//control_auth_cookie", control_message.cookie_file)
+
+ def test_multiple_auth(self):
+ """
+ Checks a response with multiple authentication methods.
+ """
+
+ control_message = stem.types.read_message(StringIO.StringIO(MULTIPLE_AUTH))
+ stem.connection.ProtocolInfoResponse.convert(control_message)
+ self.assertEquals((stem.connection.AuthMethod.COOKIE, stem.connection.AuthMethod.PASSWORD), control_message.auth_methods)
+ self.assertEquals("/home/atagar/.tor/control_auth_cookie", control_message.cookie_file)
+
+ def test_unknown_auth(self):
+ """
+ Checks a response with an unrecognized authtentication method.
+ """
+
+ control_message = stem.types.read_message(StringIO.StringIO(UNKNOWN_AUTH))
+ stem.connection.ProtocolInfoResponse.convert(control_message)
+ self.assertEquals((stem.connection.AuthMethod.UNKNOWN, stem.connection.AuthMethod.PASSWORD), control_message.auth_methods)
+ self.assertEquals(("MAGIC", "PIXIE_DUST"), control_message.unknown_auth_methods)
+
+ def test_minimum_response(self):
+ """
+ Checks a PROTOCOLINFO response that only contains the minimum amount of
+ information to be a valid response.
+ """
+
+ control_message = stem.types.read_message(StringIO.StringIO(MINIMUM_RESPONSE))
+ stem.connection.ProtocolInfoResponse.convert(control_message)
+
+ self.assertEquals(5, control_message.protocol_version)
+ self.assertEquals(None , control_message.tor_version)
+ self.assertEquals((), control_message.auth_methods)
+ self.assertEquals((), control_message.unknown_auth_methods)
+ self.assertEquals(None, control_message.cookie_file)
+ self.assertEquals(None, control_message.socket)
+
1
0
13 Nov '11
commit fc562144fd8a333ad517575976328bc2dc3cec5d
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sun Nov 13 13:43:59 2011 -0800
Including stem prefix for paths in stem comments
---
test/integ/message.py | 4 ++--
test/integ/system.py | 13 +++++++------
test/unit/types/control_line.py | 4 ++--
test/unit/types/control_message.py | 6 +++---
test/unit/types/version.py | 4 ++--
5 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/test/integ/message.py b/test/integ/message.py
index a562f86..a8e722d 100644
--- a/test/integ/message.py
+++ b/test/integ/message.py
@@ -1,5 +1,5 @@
"""
-Integration tests for the types.ControlMessage class.
+Integration tests for the stem.types.ControlMessage class.
"""
import re
@@ -11,7 +11,7 @@ import test.runner
class TestMessageFunctions(unittest.TestCase):
"""
- Exercises the 'types.ControlMessage' class with an actual tor instance.
+ Exercises the 'stem.types.ControlMessage' class with an actual tor instance.
"""
def test_unestablished_socket(self):
diff --git a/test/integ/system.py b/test/integ/system.py
index 09ffd24..32ac892 100644
--- a/test/integ/system.py
+++ b/test/integ/system.py
@@ -1,5 +1,5 @@
"""
-Unit tests for the util.system functions in the context of a tor process.
+Unit tests for the stem.util.system functions in the context of a tor process.
"""
import os
@@ -10,12 +10,13 @@ import stem.util.system as system
class TestSystemFunctions(unittest.TestCase):
"""
- Tests the util.system functions against the tor process that we're running.
+ Tests the stem.util.system functions against the tor process that we're
+ running.
"""
def test_is_available(self):
"""
- Checks the util.system.is_available function.
+ Checks the stem.util.system.is_available function.
"""
# since we're running tor it would be kinda sad if this didn't detect it
@@ -26,7 +27,7 @@ class TestSystemFunctions(unittest.TestCase):
def test_is_running(self):
"""
- Checks the util.system.is_running function.
+ Checks the stem.util.system.is_running function.
"""
self.assertTrue(system.is_running("tor"))
@@ -34,7 +35,7 @@ class TestSystemFunctions(unittest.TestCase):
def test_get_pid(self):
"""
- Checks the util.system.get_pid function.
+ Checks the stem.util.system.get_pid function.
"""
runner = test.runner.get_runner()
@@ -43,7 +44,7 @@ class TestSystemFunctions(unittest.TestCase):
def test_get_cwd(self):
"""
- Checks the util.system.get_cwd function.
+ Checks the stem.util.system.get_cwd function.
"""
# tor's pwd will match our process since we started it
diff --git a/test/unit/types/control_line.py b/test/unit/types/control_line.py
index bacda76..0c324e5 100644
--- a/test/unit/types/control_line.py
+++ b/test/unit/types/control_line.py
@@ -1,5 +1,5 @@
"""
-Unit tests for the types.ControlLine class.
+Unit tests for the stem.types.ControlLine class.
"""
import unittest
@@ -15,7 +15,7 @@ PROTOCOLINFO_RESPONSE = (
class TestControlLine(unittest.TestCase):
"""
- Tests methods of the types.ControlLine class.
+ Tests methods of the stem.types.ControlLine class.
"""
def test_pop_examples(self):
diff --git a/test/unit/types/control_message.py b/test/unit/types/control_message.py
index 5e9b7bc..af8fa00 100644
--- a/test/unit/types/control_message.py
+++ b/test/unit/types/control_message.py
@@ -1,5 +1,5 @@
"""
-Unit tests for the types.ControlMessage parsing and class.
+Unit tests for the stem.types.ControlMessage parsing and class.
"""
import socket
@@ -31,7 +31,7 @@ version -- The current version of Tor.
class TestControlMessage(unittest.TestCase):
"""
- Tests methods and functions related to 'types.ControlMessage'. This uses
+ Tests methods and functions related to 'stem.types.ControlMessage'. This uses
StringIO to make 'files' to mock socket input.
"""
@@ -163,7 +163,7 @@ class TestControlMessage(unittest.TestCase):
Performs some basic sanity checks that a reply mirrors its parsed result.
Returns:
- types.ControlMessage for the given input
+ stem.types.ControlMessage for the given input
"""
message = stem.types.read_message(StringIO.StringIO(controller_reply))
diff --git a/test/unit/types/version.py b/test/unit/types/version.py
index fb04641..309ee07 100644
--- a/test/unit/types/version.py
+++ b/test/unit/types/version.py
@@ -1,5 +1,5 @@
"""
-Unit tests for the types.Version parsing and class.
+Unit tests for the stem.types.Version parsing and class.
"""
import unittest
@@ -7,7 +7,7 @@ import stem.types
class TestVerion(unittest.TestCase):
"""
- Tests methods and functions related to 'types.Version'.
+ Tests methods and functions related to 'stem.types.Version'.
"""
def test_parsing(self):
1
0
13 Nov '11
commit f9aeefb2805e2ef9cd63f236c7a27308718575e9
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sun Nov 13 14:01:55 2011 -0800
Rearranging conf util to improve usability
Adding the standard configuration header (... sooo helpful) and moving the rest
of the util's contents around to be more intuitive.
---
stem/util/conf.py | 398 +++++++++++++++++++++++++++--------------------------
1 files changed, 205 insertions(+), 193 deletions(-)
diff --git a/stem/util/conf.py b/stem/util/conf.py
index 7581a98..7ba2f11 100644
--- a/stem/util/conf.py
+++ b/stem/util/conf.py
@@ -3,73 +3,26 @@ This provides handlers for specially formatted configuration files. Entries are
expected to consist of simple key/value pairs, and anything after "#" is
stripped as a comment. Excess whitespace is trimmed and empty lines are
ignored. For instance:
-# This is my sample config
-user.name Galen
-user.password yabba1234 # here's an inline comment
-user.notes takes a fancy to pepperjack chese
-blankEntry.example
+ # This is my sample config
+ user.name Galen
+ user.password yabba1234 # here's an inline comment
+ user.notes takes a fancy to pepperjack chese
+ blankEntry.example
-would be loaded as four entries (the last one's value being an empty string).
-If a key's defined multiple times then the last instance of it is used.
+would be loaded as four entries, the last one's value being an empty string.
-Example usage:
- User has a file at '/home/atagar/myConfig' with...
- destination.ip 1.2.3.4
- destination.port blarg
-
- startup.run export PATH=$PATH:~/bin
- startup.run alias l=ls
-
- And they have a script with...
- import stem.util.conf
-
- # Configuration values we'll use in this file. These are mappings of
- # configuration keys to the default values we'll use if the user doesn't
- # have something different in their config file (or it doesn't match this
- # type).
-
- ssh_config = {"login.user": "atagar",
- "login.password": "pepperjack_is_awesome!",
- "destination.ip": "127.0.0.1",
- "destination.port": 22,
- "startup.run": []}
-
- # Makes an empty config instance with the handle of 'ssh_login'. This is a
- # singleton so other classes can fetch this same configuration from this
- # handle.
-
- user_config = stem.util.conf.get_config("ssh_login")
-
- # Loads the user's configuration file, warning if this fails.
-
- try:
- user_config.load("/home/atagar/myConfig")
- except IOError, exc:
- print "Unable to load the user's config: %s" % exc
-
- # Replaces the contents of ssh_config with the values from the user's
- # config file if...
- # - the key is present in the config file
- # - we're able to convert the configuration file's value to the same type
- # as what's in the mapping (see the Config.get() method for how these
- # type inferences work)
- #
- # For instance in this case the login values are left alone (because they
- # aren't in the user's config file), and the 'destination.port' is also
- # left with the value of 22 because we can't turn "blarg" into an integer.
- #
- # The other values are replaced, so ssh_config now becomes...
- # {"login.user": "atagar",
- # "login.password": "pepperjack_is_awesome!",
- # "destination.ip": "1.2.3.4",
- # "destination.port": 22,
- # "startup.run": ["export PATH=$PATH:~/bin", "alias l=ls"]}
- #
- # Information for what values fail to load and why are reported to
- # 'stem.util.log'.
-
- user_config.update(ssh_config)
+get_config - Singleton for getting configurations
+Config - Custom configuration.
+ |- load - reads a configuration file
+ |- clear - empties our loaded configuration contents
+ |- update - replaces mappings in a dictionary with the config's values
+ |- keys - provides keys in the loaded configuration
+ |- unused_keys - provides keys that have never been requested
+ |- get - provides the value for a given key, with type inference
+ |- get_value - provides the value for a given key as a string
+ |- get_str_csv - gets a value as a comma separated list of strings
+ +- get_int_csv - gets a value as a comma separated list of integers
"""
import logging
@@ -107,6 +60,65 @@ class Config():
"""
Handler for easily working with custom configurations, providing persistence
to and from files. All operations are thread safe.
+
+ Example usage:
+ User has a file at '/home/atagar/myConfig' with...
+ destination.ip 1.2.3.4
+ destination.port blarg
+
+ startup.run export PATH=$PATH:~/bin
+ startup.run alias l=ls
+
+ And they have a script with...
+ import stem.util.conf
+
+ # Configuration values we'll use in this file. These are mappings of
+ # configuration keys to the default values we'll use if the user doesn't
+ # have something different in their config file (or it doesn't match this
+ # type).
+
+ ssh_config = {"login.user": "atagar",
+ "login.password": "pepperjack_is_awesome!",
+ "destination.ip": "127.0.0.1",
+ "destination.port": 22,
+ "startup.run": []}
+
+ # Makes an empty config instance with the handle of 'ssh_login'. This is
+ # a singleton so other classes can fetch this same configuration from
+ # this handle.
+
+ user_config = stem.util.conf.get_config("ssh_login")
+
+ # Loads the user's configuration file, warning if this fails.
+
+ try:
+ user_config.load("/home/atagar/myConfig")
+ except IOError, exc:
+ print "Unable to load the user's config: %s" % exc
+
+ # Replaces the contents of ssh_config with the values from the user's
+ # config file if...
+ # - the key is present in the config file
+ # - we're able to convert the configuration file's value to the same type
+ # as what's in the mapping (see the Config.get() method for how these
+ # type inferences work)
+ #
+ # For instance in this case the login values are left alone (because they
+ # aren't in the user's config file), and the 'destination.port' is also
+ # left with the value of 22 because we can't turn "blarg" into an
+ # integer.
+ #
+ # The other values are replaced, so ssh_config now becomes...
+ # {"login.user": "atagar",
+ # "login.password": "pepperjack_is_awesome!",
+ # "destination.ip": "1.2.3.4",
+ # "destination.port": 22,
+ # "startup.run": ["export PATH=$PATH:~/bin", "alias l=ls"]}
+ #
+ # Information for what values fail to load and why are reported to
+ # 'stem.util.log'.
+
+ user_config.update(ssh_config)
"""
def __init__(self):
@@ -124,35 +136,116 @@ class Config():
# keys that have been requested (used to provide unused config contents)
self._requested_keys = set()
- def get_value(self, key, default = None, multiple = False):
+ def load(self, path):
"""
- This provides the currently value associated with a given key.
+ Reads in the contents of the given path, adding its configuration values
+ to our current contents.
Arguments:
- key (str) - config setting to be fetched
- default (object) - value provided if no such key exists
- multiple (bool) - provides back a list of all values if true, otherwise
- this returns the last loaded configuration value
+ path (str) - file path to be loaded
- Returns:
- string or list of string configuration values associated with the given
- key, providing the default if no such key exists
+ Raises:
+ IOError if we fail to read the file (it doesn't exist, insufficient
+ permissions, etc)
"""
+ config_file = open(path, "r")
+ read_contents = config_file.readlines()
+ config_file.close()
+
self._contents_lock.acquire()
+ self._raw_contents = read_contents
- if key in self._contents:
- val = self._contents[key]
- if not multiple: val = val[-1]
- self._requested_keys.add(key)
- else:
- msg = "config entry '%s' not found, defaulting to '%s'" % (key, default)
- LOGGER.debug(msg)
- val = default
+ for line in self._raw_contents:
+ # strips any commenting or excess whitespace
+ comment_start = line.find("#")
+ if comment_start != -1: line = line[:comment_start]
+ line = line.strip()
+
+ # parse the key/value pair
+ if line:
+ if " " in line:
+ key, value = line.split(" ", 1)
+ value = value.strip()
+ else:
+ key, value = line, ""
+
+ if key in self._contents: self._contents[key].append(value)
+ else: self._contents[key] = [value]
+ self._path = path
self._contents_lock.release()
+
+ def clear(self):
+ """
+ Drops the configuration contents and reverts back to a blank, unloaded
+ state.
+ """
- return val
+ self._contents_lock.acquire()
+ self._path = None
+ self._contents.clear()
+ self._raw_contents = []
+ self._requested_keys = set()
+ self._contents_lock.release()
+
+ def update(self, conf_mappings, limits = None):
+ """
+ This takes a dictionary of 'config_key => default_value' mappings and
+ changes the values to reflect our current configuration. This will leave
+ the previous values alone if...
+
+ a. we don't have a value for that config_key
+ b. we can't convert our value to be the same type as the default_value
+
+ For more information about how we convert types see our get() method.
+
+ Arguments:
+ conf_mappings (dict) - configuration key/value mappings to be revised
+ limits (dict) - mappings of limits on numeric values, expected to
+ be of the form "configKey -> min" or "configKey ->
+ (min, max)"
+ """
+
+ if limits == None: limits = {}
+
+ for entry in conf_mappings.keys():
+ val = self.get(entry, conf_mappings[entry])
+
+ # if this was a numeric value then apply constraints
+ if entry in limits and (isinstance(val, int) or isinstance(val, float)):
+ if isinstance(limits[entry], tuple):
+ val = max(val, limits[entry][0])
+ val = min(val, limits[entry][1])
+ else: val = max(val, limits[entry])
+
+ # only use this value if it wouldn't change the type of the mapping (this
+ # will only fail if the type isn't either a string or one of the types
+ # recognized by the get method)
+
+ if type(val) == type(conf_mappings[entry]):
+ conf_mappings[entry] = val
+
+ def keys(self):
+ """
+ Provides all keys in the currently loaded configuration.
+
+ Returns:
+ list if strings for the configuration keys we've loaded
+ """
+
+ return self._contents.keys()
+
+ def unused_keys(self):
+ """
+ Provides the configuration keys that have never been provided to a caller
+ via the get, get_value, or update methods.
+
+ Returns:
+ set of configuration keys we've loaded but have never been requested
+ """
+
+ return set(self.get_keys()).difference(self._requested_keys)
def get(self, key, default = None):
"""
@@ -242,6 +335,36 @@ class Config():
return val
+ def get_value(self, key, default = None, multiple = False):
+ """
+ This provides the currently value associated with a given key.
+
+ Arguments:
+ key (str) - config setting to be fetched
+ default (object) - value provided if no such key exists
+ multiple (bool) - provides back a list of all values if true, otherwise
+ this returns the last loaded configuration value
+
+ Returns:
+ string or list of string configuration values associated with the given
+ key, providing the default if no such key exists
+ """
+
+ self._contents_lock.acquire()
+
+ if key in self._contents:
+ val = self._contents[key]
+ if not multiple: val = val[-1]
+ self._requested_keys.add(key)
+ else:
+ msg = "config entry '%s' not found, defaulting to '%s'" % (key, default)
+ LOGGER.debug(msg)
+ val = default
+
+ self._contents_lock.release()
+
+ return val
+
def get_str_csv(self, key, default = None, count = None):
"""
Fetches the given key as a comma separated value.
@@ -319,115 +442,4 @@ class Config():
LOGGER.info(error_msg)
return default
else: return [int(val) for val in conf_comp]
-
- def update(self, conf_mappings, limits = None):
- """
- This takes a dictionary of 'config_key => default_value' mappings and
- changes the values to reflect our current configuration. This will leave
- the previous values alone if...
-
- a. we don't have a value for that config_key
- b. we can't convert our value to be the same type as the default_value
-
- For more information about how we convert types see our get() method.
-
- Arguments:
- conf_mappings (dict) - configuration key/value mappings to be revised
- limits (dict) - mappings of limits on numeric values, expected to
- be of the form "configKey -> min" or "configKey ->
- (min, max)"
- """
-
- if limits == None: limits = {}
-
- for entry in conf_mappings.keys():
- val = self.get(entry, conf_mappings[entry])
-
- # if this was a numeric value then apply constraints
- if entry in limits and (isinstance(val, int) or isinstance(val, float)):
- if isinstance(limits[entry], tuple):
- val = max(val, limits[entry][0])
- val = min(val, limits[entry][1])
- else: val = max(val, limits[entry])
-
- # only use this value if it wouldn't change the type of the mapping (this
- # will only fail if the type isn't either a string or one of the types
- # recognized by the get method)
-
- if type(val) == type(conf_mappings[entry]):
- conf_mappings[entry] = val
-
- def keys(self):
- """
- Provides all keys in the currently loaded configuration.
-
- Returns:
- list if strings for the configuration keys we've loaded
- """
-
- return self._contents.keys()
-
- def unused_keys(self):
- """
- Provides the configuration keys that have never been provided to a caller
- via the get, get_value, or update methods.
-
- Returns:
- set of configuration keys we've loaded but have never been requested
- """
-
- return set(self.get_keys()).difference(self._requested_keys)
-
- def reset(self):
- """
- Drops the configuration contents and reverts back to a blank, unloaded
- state.
- """
-
- self._contents_lock.acquire()
- self._path = None
- self._contents.clear()
- self._raw_contents = []
- self._requested_keys = set()
- self._contents_lock.release()
-
- def load(self, path):
- """
- Reads in the contents of the given path, adding its configuration values
- to our current contents.
-
- Arguments:
- path (str) - file path to be loaded
-
- Raises:
- IOError if we fail to read the file (it doesn't exist, insufficient
- permissions, etc)
- """
-
- config_file = open(path, "r")
- read_contents = config_file.readlines()
- config_file.close()
-
- self._contents_lock.acquire()
- self._raw_contents = read_contents
-
- for line in self._raw_contents:
- # strips any commenting or excess whitespace
- comment_start = line.find("#")
- if comment_start != -1: line = line[:comment_start]
- line = line.strip()
-
- # parse the key/value pair
- if line:
- if " " in line:
- key, value = line.split(" ", 1)
- value = value.strip()
- else:
- key, value = line, ""
-
- if key in self._contents: self._contents[key].append(value)
- else: self._contents[key] = [value]
-
- self._path = path
- self._contents_lock.release()
1
0
commit d30e229c325bc243697d1d015a7bda03082c9756
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sun Nov 13 15:02:47 2011 -0800
Unit tests for enum
---
run_tests.py | 2 +
test/unit/util/__init__.py | 6 ++++
test/unit/util/enum.py | 59 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 67 insertions(+), 0 deletions(-)
diff --git a/run_tests.py b/run_tests.py
index 1107a59..530466a 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -16,6 +16,7 @@ import test.unit.types.control_message
import test.unit.types.control_line
import test.unit.types.version
import test.unit.connection.protocolinfo_response
+import test.unit.util.enum
import test.integ.message
import test.integ.system
@@ -31,6 +32,7 @@ UNIT_TESTS = (("stem.types.ControlMessage", test.unit.types.control_message.Test
("stem.types.ControlLine", test.unit.types.control_line.TestControlLine),
("stem.types.Version", test.unit.types.version.TestVerion),
("stem.connection.ProtocolInfoResponse", test.unit.connection.protocolinfo_response.TestProtocolInfoResponse),
+ ("stem.util.enum", test.unit.util.enum.TestEnum),
)
INTEG_TESTS = (("stem.types.ControlMessage", test.integ.message.TestMessageFunctions),
diff --git a/test/unit/util/__init__.py b/test/unit/util/__init__.py
new file mode 100644
index 0000000..84f12bf
--- /dev/null
+++ b/test/unit/util/__init__.py
@@ -0,0 +1,6 @@
+"""
+Unit tests for stem.util.* contents.
+"""
+
+__all__ = ["enum"]
+
diff --git a/test/unit/util/enum.py b/test/unit/util/enum.py
new file mode 100644
index 0000000..abdff06
--- /dev/null
+++ b/test/unit/util/enum.py
@@ -0,0 +1,59 @@
+"""
+Unit tests for the stem.util.enum class and functions.
+"""
+
+import unittest
+import stem.util.enum
+
+class TestEnum(unittest.TestCase):
+ """
+ Tests the stem.util.enum contents.
+ """
+
+ def test_to_camel_case(self):
+ """
+ Checks the stem.util.enum.to_camel_case function.
+ """
+
+ # test the pydoc example
+ self.assertEquals("I Like Pepperjack!", stem.util.enum.to_camel_case("I_LIKE_PEPPERJACK!"))
+
+ # check a few edge cases
+ self.assertEquals("", stem.util.enum.to_camel_case(""))
+ self.assertEquals("Hello", stem.util.enum.to_camel_case("hello"))
+ self.assertEquals("Hello", stem.util.enum.to_camel_case("HELLO"))
+ self.assertEquals("Hello World", stem.util.enum.to_camel_case("hello__world"))
+ self.assertEquals("Hello\tworld", stem.util.enum.to_camel_case("hello\tWORLD"))
+ self.assertEquals("Hello\t\tWorld", stem.util.enum.to_camel_case("hello__world", "\t"))
+
+ def test_enum_examples(self):
+ """
+ Checks that the pydoc examples are accurate.
+ """
+
+ insects = stem.util.enum.Enum("ANT", "WASP", "LADYBUG", "FIREFLY")
+ self.assertEquals("Ant", insects.ANT)
+ self.assertEquals(("Ant", "Wasp", "Ladybug", "Firefly"), insects.values())
+
+ pets = stem.util.enum.Enum(("DOG", "Skippy"), "CAT", ("FISH", "Nemo"))
+ self.assertEquals("Skippy", pets.DOG)
+ self.assertEquals("Cat", pets.CAT)
+
+ def test_enum_methods(self):
+ """
+ Exercises enumeration methods.
+ """
+
+ insects = stem.util.enum.Enum("ANT", "WASP", "LADYBUG", "FIREFLY")
+
+ # next method
+ self.assertEquals(insects.WASP, insects.next(insects.ANT))
+ self.assertEquals(insects.ANT, insects.next(insects.FIREFLY))
+
+ # previous method
+ self.assertEquals(insects.FIREFLY, insects.previous(insects.ANT))
+ self.assertEquals(insects.LADYBUG, insects.previous(insects.FIREFLY))
+
+ # __iter__ method
+ self.assertEquals(("ANT", "WASP", "LADYBUG", "FIREFLY"), tuple(insects))
+
1
0
13 Nov '11
commit b34f8990b6604996d7d60d139267ae43bac1de02
Author: Damian Johnson <atagar(a)torproject.org>
Date: Sun Nov 13 15:09:51 2011 -0800
Shuffling integ tests to match unit tests
Unit tests are nicely categorized under their respective modules, so reordering
integration tests to match.
---
run_tests.py | 8 +-
stem/util/__init__.py | 2 +-
test/integ/__init__.py | 2 +-
test/integ/message.py | 242 -----------------------------------
test/integ/system.py | 64 ---------
test/integ/types/__init__.py | 6 +
test/integ/types/control_message.py | 242 +++++++++++++++++++++++++++++++++++
test/integ/util/__init__.py | 6 +
test/integ/util/system.py | 65 ++++++++++
9 files changed, 325 insertions(+), 312 deletions(-)
diff --git a/run_tests.py b/run_tests.py
index 530466a..7dcffaf 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -17,8 +17,8 @@ import test.unit.types.control_line
import test.unit.types.version
import test.unit.connection.protocolinfo_response
import test.unit.util.enum
-import test.integ.message
-import test.integ.system
+import test.integ.types.control_message
+import test.integ.util.system
import stem.util.enum
import stem.util.term as term
@@ -35,8 +35,8 @@ UNIT_TESTS = (("stem.types.ControlMessage", test.unit.types.control_message.Test
("stem.util.enum", test.unit.util.enum.TestEnum),
)
-INTEG_TESTS = (("stem.types.ControlMessage", test.integ.message.TestMessageFunctions),
- ("stem.util.system", test.integ.system.TestSystemFunctions),
+INTEG_TESTS = (("stem.types.ControlMessage", test.integ.types.control_message.TestControlMessage),
+ ("stem.util.system", test.integ.util.system.TestSystem),
)
# TODO: drop targets?
diff --git a/stem/util/__init__.py b/stem/util/__init__.py
index 14692fe..42569c9 100644
--- a/stem/util/__init__.py
+++ b/stem/util/__init__.py
@@ -16,5 +16,5 @@ stem_logger = logging.getLogger("stem")
if not stem_logger.handlers:
stem_logger.addHandler(NullHandler())
-__all__ = ["conf", "enum", "log", "proc", "system", "term"]
+__all__ = ["conf", "enum", "proc", "system", "term"]
diff --git a/test/integ/__init__.py b/test/integ/__init__.py
index 718d40a..b96692a 100644
--- a/test/integ/__init__.py
+++ b/test/integ/__init__.py
@@ -2,5 +2,5 @@
Integration tests for the stem library.
"""
-__all__ = ["message", "system"]
+__all__ = []
diff --git a/test/integ/message.py b/test/integ/message.py
deleted file mode 100644
index a8e722d..0000000
--- a/test/integ/message.py
+++ /dev/null
@@ -1,242 +0,0 @@
-"""
-Integration tests for the stem.types.ControlMessage class.
-"""
-
-import re
-import socket
-import unittest
-
-import stem.types
-import test.runner
-
-class TestMessageFunctions(unittest.TestCase):
- """
- Exercises the 'stem.types.ControlMessage' class with an actual tor instance.
- """
-
- def test_unestablished_socket(self):
- """
- Checks message parsing when we have a valid but unauthenticated socket.
- """
-
- control_socket, control_socket_file = self._get_control_socket(False)
-
- # If an unauthenticated connection gets a message besides AUTHENTICATE or
- # PROTOCOLINFO then tor will give an 'Authentication required.' message and
- # hang up.
-
- control_socket_file.write("GETINFO version\r\n")
- control_socket_file.flush()
-
- auth_required_response = stem.types.read_message(control_socket_file)
- self.assertEquals("Authentication required.", str(auth_required_response))
- self.assertEquals(["Authentication required."], list(auth_required_response))
- self.assertEquals("514 Authentication required.\r\n", auth_required_response.raw_content())
- self.assertEquals([("514", " ", "Authentication required.")], auth_required_response.content())
-
- # The socket's broken but doesn't realize it yet. Send another message and
- # it should fail with a closed exception.
-
- control_socket_file.write("GETINFO version\r\n")
- control_socket_file.flush()
-
- self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
-
- # Additional socket usage should fail, and pulling more responses will fail
- # with more closed exceptions.
-
- control_socket_file.write("GETINFO version\r\n")
- self.assertRaises(socket.error, control_socket_file.flush)
- self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
- self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
- self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
-
- # The socket connection is already broken so calling close shouldn't have
- # an impact.
-
- control_socket.close()
- control_socket_file.write("GETINFO version\r\n")
- self.assertRaises(socket.error, control_socket_file.flush)
- self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
-
- # Closing the file handler, however, will cause a different type of error.
- # This seems to depend on the python version, in 2.6 we get an
- # AttributeError and in 2.7 the close() call raises...
- # error: [Errno 32] Broken pipe
-
- try:
- control_socket_file.close()
- control_socket_file.write("GETINFO version\r\n")
- except: pass
-
- # receives: AttributeError: 'NoneType' object has no attribute 'sendall'
- self.assertRaises(AttributeError, control_socket_file.flush)
-
- # receives: stem.types.SocketClosed: socket file has been closed
- self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
-
- def test_invalid_command(self):
- """
- Parses the response for a command which doesn't exist.
- """
-
- control_socket, control_socket_file = self._get_control_socket()
-
- control_socket_file.write("blarg\r\n")
- control_socket_file.flush()
-
- unrecognized_command_response = stem.types.read_message(control_socket_file)
- self.assertEquals('Unrecognized command "blarg"', str(unrecognized_command_response))
- self.assertEquals(['Unrecognized command "blarg"'], list(unrecognized_command_response))
- self.assertEquals('510 Unrecognized command "blarg"\r\n', unrecognized_command_response.raw_content())
- self.assertEquals([('510', ' ', 'Unrecognized command "blarg"')], unrecognized_command_response.content())
-
- control_socket.close()
- control_socket_file.close()
-
- def test_invalid_getinfo(self):
- """
- Parses the response for a GETINFO query which doesn't exist.
- """
-
- control_socket, control_socket_file = self._get_control_socket()
-
- control_socket_file.write("GETINFO blarg\r\n")
- control_socket_file.flush()
-
- unrecognized_key_response = stem.types.read_message(control_socket_file)
- self.assertEquals('Unrecognized key "blarg"', str(unrecognized_key_response))
- self.assertEquals(['Unrecognized key "blarg"'], list(unrecognized_key_response))
- self.assertEquals('552 Unrecognized key "blarg"\r\n', unrecognized_key_response.raw_content())
- self.assertEquals([('552', ' ', 'Unrecognized key "blarg"')], unrecognized_key_response.content())
-
- control_socket.close()
- control_socket_file.close()
-
- def test_getinfo_config_file(self):
- """
- Parses the 'GETINFO config-file' response.
- """
-
- runner = test.runner.get_runner()
- torrc_dst = runner.get_torrc_path()
-
- control_socket, control_socket_file = self._get_control_socket()
-
- control_socket_file.write("GETINFO config-file\r\n")
- control_socket_file.flush()
-
- config_file_response = stem.types.read_message(control_socket_file)
- self.assertEquals("config-file=%s\nOK" % torrc_dst, str(config_file_response))
- self.assertEquals(["config-file=%s" % torrc_dst, "OK"], list(config_file_response))
- self.assertEquals("250-config-file=%s\r\n250 OK\r\n" % torrc_dst, config_file_response.raw_content())
- self.assertEquals([("250", "-", "config-file=%s" % torrc_dst), ("250", " ", "OK")], config_file_response.content())
-
- control_socket.close()
- control_socket_file.close()
-
- def test_getinfo_config_text(self):
- """
- Parses the 'GETINFO config-text' response.
- """
-
- if stem.process.get_tor_version() < stem.types.REQ_GETINFO_CONFIG_TEXT:
- return
-
- # We can't be certain of the order, and there may be extra config-text
- # entries as per...
- # https://trac.torproject.org/projects/tor/ticket/2362
- #
- # so we'll just check that the response is a superset of our config
-
- runner = test.runner.get_runner()
- torrc_contents = []
-
- for line in runner.get_torrc_contents().split("\n"):
- line = line.strip()
-
- if line and not line.startswith("#"):
- torrc_contents.append(line)
-
- control_socket, control_socket_file = self._get_control_socket()
-
- control_socket_file.write("GETINFO config-text\r\n")
- control_socket_file.flush()
-
- config_text_response = stem.types.read_message(control_socket_file)
-
- # the response should contain two entries, the first being a data response
- self.assertEqual(2, len(list(config_text_response)))
- self.assertEqual("OK", list(config_text_response)[1])
- self.assertEqual(("250", " ", "OK"), config_text_response.content()[1])
- self.assertTrue(config_text_response.raw_content().startswith("250+config-text=\r\n"))
- self.assertTrue(config_text_response.raw_content().endswith("\r\n.\r\n250 OK\r\n"))
- self.assertTrue(str(config_text_response).startswith("config-text=\n"))
- self.assertTrue(str(config_text_response).endswith("\nOK"))
-
- for torrc_entry in torrc_contents:
- self.assertTrue("\n%s\n" % torrc_entry in str(config_text_response))
- self.assertTrue(torrc_entry in list(config_text_response)[0])
- self.assertTrue("%s\r\n" % torrc_entry in config_text_response.raw_content())
- self.assertTrue("%s" % torrc_entry in config_text_response.content()[0][2])
-
- control_socket.close()
- control_socket_file.close()
-
- def test_bw_event(self):
- """
- Issues 'SETEVENTS BW' and parses a few events.
- """
-
- control_socket, control_socket_file = self._get_control_socket()
-
- control_socket_file.write("SETEVENTS BW\r\n")
- control_socket_file.flush()
-
- setevents_response = stem.types.read_message(control_socket_file)
- self.assertEquals("OK", str(setevents_response))
- self.assertEquals(["OK"], list(setevents_response))
- self.assertEquals("250 OK\r\n", setevents_response.raw_content())
- self.assertEquals([("250", " ", "OK")], setevents_response.content())
-
- # Tor will emit a BW event once per second. Parsing two of them.
-
- for _ in range(2):
- bw_event = stem.types.read_message(control_socket_file)
- self.assertTrue(re.match("BW [0-9]+ [0-9]+", str(bw_event)))
- self.assertTrue(re.match("650 BW [0-9]+ [0-9]+\r\n", bw_event.raw_content()))
- self.assertEquals(("650", " "), bw_event.content()[0][:2])
-
- control_socket.close()
- control_socket_file.close()
-
- def _get_control_socket(self, authenticate = True):
- """
- Provides a socket connected to the tor test instance's control port.
-
- Arguments:
- authenticate (bool) - if True then the socket is authenticated
-
- Returns:
- (socket.socket, file) tuple with the control socket and its file
- """
-
- runner = test.runner.get_runner()
-
- control_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- control_socket.connect(("127.0.0.1", runner.get_control_port()))
- control_socket_file = control_socket.makefile()
-
- if authenticate:
- control_socket_file.write("AUTHENTICATE\r\n")
- control_socket_file.flush()
-
- authenticate_response = stem.types.read_message(control_socket_file)
-
- self.assertEquals("OK", str(authenticate_response))
- self.assertEquals(["OK"], list(authenticate_response))
- self.assertEquals("250 OK\r\n", authenticate_response.raw_content())
- self.assertEquals([("250", " ", "OK")], authenticate_response.content())
-
- return (control_socket, control_socket_file)
-
diff --git a/test/integ/system.py b/test/integ/system.py
deleted file mode 100644
index 32ac892..0000000
--- a/test/integ/system.py
+++ /dev/null
@@ -1,64 +0,0 @@
-"""
-Unit tests for the stem.util.system functions in the context of a tor process.
-"""
-
-import os
-import unittest
-
-import test.runner
-import stem.util.system as system
-
-class TestSystemFunctions(unittest.TestCase):
- """
- Tests the stem.util.system functions against the tor process that we're
- running.
- """
-
- def test_is_available(self):
- """
- Checks the stem.util.system.is_available function.
- """
-
- # since we're running tor it would be kinda sad if this didn't detect it
- self.assertTrue(system.is_available("tor"))
-
- # but it would be kinda weird if this did...
- self.assertFalse(system.is_available("blarg_and_stuff"))
-
- def test_is_running(self):
- """
- Checks the stem.util.system.is_running function.
- """
-
- self.assertTrue(system.is_running("tor"))
- self.assertFalse(system.is_running("blarg_and_stuff"))
-
- def test_get_pid(self):
- """
- Checks the stem.util.system.get_pid function.
- """
-
- runner = test.runner.get_runner()
- self.assertEquals(runner.get_pid(), system.get_pid("tor", runner.get_control_port()))
- self.assertEquals(None, system.get_pid("blarg_and_stuff"))
-
- def test_get_cwd(self):
- """
- Checks the stem.util.system.get_cwd function.
- """
-
- # tor's pwd will match our process since we started it
- runner = test.runner.get_runner()
- self.assertEquals(os.getcwd(), system.get_cwd(runner.get_pid()))
- self.assertEquals(None, system.get_cwd(99999, True))
- self.assertRaises(IOError, system.get_cwd, 99999, False)
-
- def test_get_bsd_jail_id(self):
- """
- Exercises the util.system.get_bsd_jail_id function, running through the
- failure case (since I'm not on BSD I can't really test this function
- properly).
- """
-
- self.assertEquals(0, system.get_bsd_jail_id(99999))
-
diff --git a/test/integ/types/__init__.py b/test/integ/types/__init__.py
new file mode 100644
index 0000000..7ab4c07
--- /dev/null
+++ b/test/integ/types/__init__.py
@@ -0,0 +1,6 @@
+"""
+Integration tests for stem.types.
+"""
+
+__all__ = ["control_message"]
+
diff --git a/test/integ/types/control_message.py b/test/integ/types/control_message.py
new file mode 100644
index 0000000..07259e7
--- /dev/null
+++ b/test/integ/types/control_message.py
@@ -0,0 +1,242 @@
+"""
+Integration tests for the stem.types.ControlMessage class.
+"""
+
+import re
+import socket
+import unittest
+
+import stem.types
+import test.runner
+
+class TestControlMessage(unittest.TestCase):
+ """
+ Exercises the 'stem.types.ControlMessage' class with an actual tor instance.
+ """
+
+ def test_unestablished_socket(self):
+ """
+ Checks message parsing when we have a valid but unauthenticated socket.
+ """
+
+ control_socket, control_socket_file = self._get_control_socket(False)
+
+ # If an unauthenticated connection gets a message besides AUTHENTICATE or
+ # PROTOCOLINFO then tor will give an 'Authentication required.' message and
+ # hang up.
+
+ control_socket_file.write("GETINFO version\r\n")
+ control_socket_file.flush()
+
+ auth_required_response = stem.types.read_message(control_socket_file)
+ self.assertEquals("Authentication required.", str(auth_required_response))
+ self.assertEquals(["Authentication required."], list(auth_required_response))
+ self.assertEquals("514 Authentication required.\r\n", auth_required_response.raw_content())
+ self.assertEquals([("514", " ", "Authentication required.")], auth_required_response.content())
+
+ # The socket's broken but doesn't realize it yet. Send another message and
+ # it should fail with a closed exception.
+
+ control_socket_file.write("GETINFO version\r\n")
+ control_socket_file.flush()
+
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
+
+ # Additional socket usage should fail, and pulling more responses will fail
+ # with more closed exceptions.
+
+ control_socket_file.write("GETINFO version\r\n")
+ self.assertRaises(socket.error, control_socket_file.flush)
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
+
+ # The socket connection is already broken so calling close shouldn't have
+ # an impact.
+
+ control_socket.close()
+ control_socket_file.write("GETINFO version\r\n")
+ self.assertRaises(socket.error, control_socket_file.flush)
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
+
+ # Closing the file handler, however, will cause a different type of error.
+ # This seems to depend on the python version, in 2.6 we get an
+ # AttributeError and in 2.7 the close() call raises...
+ # error: [Errno 32] Broken pipe
+
+ try:
+ control_socket_file.close()
+ control_socket_file.write("GETINFO version\r\n")
+ except: pass
+
+ # receives: AttributeError: 'NoneType' object has no attribute 'sendall'
+ self.assertRaises(AttributeError, control_socket_file.flush)
+
+ # receives: stem.types.SocketClosed: socket file has been closed
+ self.assertRaises(stem.types.SocketClosed, stem.types.read_message, control_socket_file)
+
+ def test_invalid_command(self):
+ """
+ Parses the response for a command which doesn't exist.
+ """
+
+ control_socket, control_socket_file = self._get_control_socket()
+
+ control_socket_file.write("blarg\r\n")
+ control_socket_file.flush()
+
+ unrecognized_command_response = stem.types.read_message(control_socket_file)
+ self.assertEquals('Unrecognized command "blarg"', str(unrecognized_command_response))
+ self.assertEquals(['Unrecognized command "blarg"'], list(unrecognized_command_response))
+ self.assertEquals('510 Unrecognized command "blarg"\r\n', unrecognized_command_response.raw_content())
+ self.assertEquals([('510', ' ', 'Unrecognized command "blarg"')], unrecognized_command_response.content())
+
+ control_socket.close()
+ control_socket_file.close()
+
+ def test_invalid_getinfo(self):
+ """
+ Parses the response for a GETINFO query which doesn't exist.
+ """
+
+ control_socket, control_socket_file = self._get_control_socket()
+
+ control_socket_file.write("GETINFO blarg\r\n")
+ control_socket_file.flush()
+
+ unrecognized_key_response = stem.types.read_message(control_socket_file)
+ self.assertEquals('Unrecognized key "blarg"', str(unrecognized_key_response))
+ self.assertEquals(['Unrecognized key "blarg"'], list(unrecognized_key_response))
+ self.assertEquals('552 Unrecognized key "blarg"\r\n', unrecognized_key_response.raw_content())
+ self.assertEquals([('552', ' ', 'Unrecognized key "blarg"')], unrecognized_key_response.content())
+
+ control_socket.close()
+ control_socket_file.close()
+
+ def test_getinfo_config_file(self):
+ """
+ Parses the 'GETINFO config-file' response.
+ """
+
+ runner = test.runner.get_runner()
+ torrc_dst = runner.get_torrc_path()
+
+ control_socket, control_socket_file = self._get_control_socket()
+
+ control_socket_file.write("GETINFO config-file\r\n")
+ control_socket_file.flush()
+
+ config_file_response = stem.types.read_message(control_socket_file)
+ self.assertEquals("config-file=%s\nOK" % torrc_dst, str(config_file_response))
+ self.assertEquals(["config-file=%s" % torrc_dst, "OK"], list(config_file_response))
+ self.assertEquals("250-config-file=%s\r\n250 OK\r\n" % torrc_dst, config_file_response.raw_content())
+ self.assertEquals([("250", "-", "config-file=%s" % torrc_dst), ("250", " ", "OK")], config_file_response.content())
+
+ control_socket.close()
+ control_socket_file.close()
+
+ def test_getinfo_config_text(self):
+ """
+ Parses the 'GETINFO config-text' response.
+ """
+
+ if stem.process.get_tor_version() < stem.types.REQ_GETINFO_CONFIG_TEXT:
+ self.skipTest("(requires %s)" % stem.types.REQ_GETINFO_CONFIG_TEXT)
+
+ # We can't be certain of the order, and there may be extra config-text
+ # entries as per...
+ # https://trac.torproject.org/projects/tor/ticket/2362
+ #
+ # so we'll just check that the response is a superset of our config
+
+ runner = test.runner.get_runner()
+ torrc_contents = []
+
+ for line in runner.get_torrc_contents().split("\n"):
+ line = line.strip()
+
+ if line and not line.startswith("#"):
+ torrc_contents.append(line)
+
+ control_socket, control_socket_file = self._get_control_socket()
+
+ control_socket_file.write("GETINFO config-text\r\n")
+ control_socket_file.flush()
+
+ config_text_response = stem.types.read_message(control_socket_file)
+
+ # the response should contain two entries, the first being a data response
+ self.assertEqual(2, len(list(config_text_response)))
+ self.assertEqual("OK", list(config_text_response)[1])
+ self.assertEqual(("250", " ", "OK"), config_text_response.content()[1])
+ self.assertTrue(config_text_response.raw_content().startswith("250+config-text=\r\n"))
+ self.assertTrue(config_text_response.raw_content().endswith("\r\n.\r\n250 OK\r\n"))
+ self.assertTrue(str(config_text_response).startswith("config-text=\n"))
+ self.assertTrue(str(config_text_response).endswith("\nOK"))
+
+ for torrc_entry in torrc_contents:
+ self.assertTrue("\n%s\n" % torrc_entry in str(config_text_response))
+ self.assertTrue(torrc_entry in list(config_text_response)[0])
+ self.assertTrue("%s\r\n" % torrc_entry in config_text_response.raw_content())
+ self.assertTrue("%s" % torrc_entry in config_text_response.content()[0][2])
+
+ control_socket.close()
+ control_socket_file.close()
+
+ def test_bw_event(self):
+ """
+ Issues 'SETEVENTS BW' and parses a few events.
+ """
+
+ control_socket, control_socket_file = self._get_control_socket()
+
+ control_socket_file.write("SETEVENTS BW\r\n")
+ control_socket_file.flush()
+
+ setevents_response = stem.types.read_message(control_socket_file)
+ self.assertEquals("OK", str(setevents_response))
+ self.assertEquals(["OK"], list(setevents_response))
+ self.assertEquals("250 OK\r\n", setevents_response.raw_content())
+ self.assertEquals([("250", " ", "OK")], setevents_response.content())
+
+ # Tor will emit a BW event once per second. Parsing two of them.
+
+ for _ in range(2):
+ bw_event = stem.types.read_message(control_socket_file)
+ self.assertTrue(re.match("BW [0-9]+ [0-9]+", str(bw_event)))
+ self.assertTrue(re.match("650 BW [0-9]+ [0-9]+\r\n", bw_event.raw_content()))
+ self.assertEquals(("650", " "), bw_event.content()[0][:2])
+
+ control_socket.close()
+ control_socket_file.close()
+
+ def _get_control_socket(self, authenticate = True):
+ """
+ Provides a socket connected to the tor test instance's control port.
+
+ Arguments:
+ authenticate (bool) - if True then the socket is authenticated
+
+ Returns:
+ (socket.socket, file) tuple with the control socket and its file
+ """
+
+ runner = test.runner.get_runner()
+
+ control_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ control_socket.connect(("127.0.0.1", runner.get_control_port()))
+ control_socket_file = control_socket.makefile()
+
+ if authenticate:
+ control_socket_file.write("AUTHENTICATE\r\n")
+ control_socket_file.flush()
+
+ authenticate_response = stem.types.read_message(control_socket_file)
+
+ self.assertEquals("OK", str(authenticate_response))
+ self.assertEquals(["OK"], list(authenticate_response))
+ self.assertEquals("250 OK\r\n", authenticate_response.raw_content())
+ self.assertEquals([("250", " ", "OK")], authenticate_response.content())
+
+ return (control_socket, control_socket_file)
+
diff --git a/test/integ/util/__init__.py b/test/integ/util/__init__.py
new file mode 100644
index 0000000..a0b3303
--- /dev/null
+++ b/test/integ/util/__init__.py
@@ -0,0 +1,6 @@
+"""
+Integration tests for stem.util.* contents.
+"""
+
+__all__ = ["system"]
+
diff --git a/test/integ/util/system.py b/test/integ/util/system.py
new file mode 100644
index 0000000..fc7c384
--- /dev/null
+++ b/test/integ/util/system.py
@@ -0,0 +1,65 @@
+"""
+Integration tests for the stem.util.system functions in the context of a tor
+process.
+"""
+
+import os
+import unittest
+
+import test.runner
+import stem.util.system
+
+class TestSystem(unittest.TestCase):
+ """
+ Tests the stem.util.system functions against the tor process that we're
+ running.
+ """
+
+ def test_is_available(self):
+ """
+ Checks the stem.util.system.is_available function.
+ """
+
+ # since we're running tor it would be kinda sad if this didn't detect it
+ self.assertTrue(stem.util.system.is_available("tor"))
+
+ # but it would be kinda weird if this did...
+ self.assertFalse(stem.util.system.is_available("blarg_and_stuff"))
+
+ def test_is_running(self):
+ """
+ Checks the stem.util.system.is_running function.
+ """
+
+ self.assertTrue(stem.util.system.is_running("tor"))
+ self.assertFalse(stem.util.system.is_running("blarg_and_stuff"))
+
+ def test_get_pid(self):
+ """
+ Checks the stem.util.system.get_pid function.
+ """
+
+ runner = test.runner.get_runner()
+ self.assertEquals(runner.get_pid(), stem.util.system.get_pid("tor", runner.get_control_port()))
+ self.assertEquals(None, stem.util.system.get_pid("blarg_and_stuff"))
+
+ def test_get_cwd(self):
+ """
+ Checks the stem.util.system.get_cwd function.
+ """
+
+ # tor's pwd will match our process since we started it
+ runner = test.runner.get_runner()
+ self.assertEquals(os.getcwd(), stem.util.system.get_cwd(runner.get_pid()))
+ self.assertEquals(None, stem.util.system.get_cwd(99999, True))
+ self.assertRaises(IOError, stem.util.system.get_cwd, 99999, False)
+
+ def test_get_bsd_jail_id(self):
+ """
+ Exercises the stem.util.system.get_bsd_jail_id function, running through
+ the failure case (since I'm not on BSD I can't really test this function
+ properly).
+ """
+
+ self.assertEquals(0, stem.util.system.get_bsd_jail_id(99999))
+
1
0