jenkins-bot has submitted this change and it was merged.

Change subject: Skip tests that use a site which is failing
......................................................................


Skip tests that use a site which is failing

Add 'hostname' to TestCase.sites dict, and skip class when
failed to receive a useful response for the hosts homepage.

Re-enable weblib tests on travis-ci, instead using the new
automatic skip functionality to avoid errors due to WebCite
serving invalid XML and having an undecodable homepage.

Mention hostnames in test method docstring where the hostname
is not easily guessed.

Bug: T58963
Change-Id: I8fdcdaa0fab3b680d35b81b20a12ff5b786f779d
---
M pywikibot/weblib.py
M tests/__init__.py
M tests/aspects.py
M tests/data_ingestion_tests.py
M tests/http_tests.py
M tests/interwiki_link_tests.py
M tests/weblib_tests.py
M tests/wikidataquery_tests.py
M tests/wikistats_tests.py
9 files changed, 202 insertions(+), 39 deletions(-)

Approvals:
  XZise: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/pywikibot/weblib.py b/pywikibot/weblib.py
index f682fec..8f0622d 100644
--- a/pywikibot/weblib.py
+++ b/pywikibot/weblib.py
@@ -36,7 +36,7 @@
         query['timestamp'] = timestamp
 
     uri = uri + urlencode(query)
-    jsontext = http.request(uri=uri, site=None)
+    jsontext = http.fetch(uri).content
     if "closest" in jsontext:
         data = json.loads(jsontext)
         return data['archived_snapshots']['closest']['url']
@@ -65,7 +65,7 @@
         query['date'] = timestamp
 
     uri = uri + urlencode(query)
-    xmltext = http.request(uri=uri, site=None)
+    xmltext = http.fetch(uri).content
     if "success" in xmltext:
         data = ET.fromstring(xmltext)
         return data.find('.//webcite_url').text
diff --git a/tests/__init__.py b/tests/__init__.py
index 32eaa93..4edf26a 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -94,9 +94,6 @@
     'ui',
 ]
 
-if os.environ.get('TRAVIS', 'false') == 'true':
-    disabled_test_modules.append('weblib')
-
 disabled_tests = {
     'textlib': [
         'test_interwiki_format',  # example; very slow test
diff --git a/tests/aspects.py b/tests/aspects.py
index 6466018..ab9146c 100644
--- a/tests/aspects.py
+++ b/tests/aspects.py
@@ -37,9 +37,10 @@
 
 import pywikibot
 
-from pywikibot import config, log, Site
+from pywikibot import config, log, ServerError, Site
 from pywikibot.site import BaseSite
 from pywikibot.family import WikimediaFamily
+from pywikibot.comms import http
 from pywikibot.data.api import Request as _original_Request
 
 import tests
@@ -382,6 +383,70 @@
         super(CacheInfoMixin, self).tearDown()
 
 
+class CheckHostnameMixin(TestCaseBase):
+
+    """Check the hostname is online before running tests."""
+
+    _checked_hostnames = {}
+
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up the test class.
+
+        Prevent tests running if the host is down.
+        """
+        super(CheckHostnameMixin, cls).setUpClass()
+
+        if not hasattr(cls, 'sites'):
+            return
+
+        for key, data in cls.sites.items():
+            if 'hostname' not in data:
+                raise Exception('%s: hostname not defined for %s'
+                                % (cls.__name__, key))
+            hostname = data['hostname']
+
+            if hostname in cls._checked_hostnames:
+                if isinstance(cls._checked_hostnames[hostname], Exception):
+                    raise unittest.SkipTest(
+                        '%s: hostname %s failed (cached): %s'
+                        % (cls.__name__, hostname,
+                           cls._checked_hostnames[hostname]))
+                elif cls._checked_hostnames[hostname] is False:
+                    raise unittest.SkipTest('%s: hostname %s failed (cached)'
+                                            % (cls.__name__, hostname))
+                else:
+                    continue
+
+            e = None
+            try:
+                if '://' not in hostname:
+                    hostname = 'http://' + hostname
+                r = http.fetch(uri=hostname,
+                               default_error_handling=False)
+                if r.exception:
+                    e = r.exception
+                else:
+                    if r.status not in [200, 301, 302, 303, 307, 308]:
+                        raise ServerError('HTTP status: %d' % r.status)
+                    r.content  # default decode may raise exception
+            except Exception as e2:
+                pywikibot.error('%s: accessing %s caused exception:'
+                                % (cls.__name__, hostname))
+                pywikibot.exception(e2, tb=True)
+                e = e2
+                pass
+
+            if e:
+                cls._checked_hostnames[hostname] = e
+                raise unittest.SkipTest(
+                    '%s: hostname %s failed: %s'
+                    % (cls.__name__, hostname, e))
+
+            cls._checked_hostnames[hostname] = True
+
+
 class SiteWriteMixin(TestCaseBase):
 
     """
@@ -591,6 +656,8 @@
         if 'cached' in dct and dct['cached']:
             bases = tuple([ForceCacheMixin] + list(bases))
 
+        bases = tuple([CheckHostnameMixin] + list(bases))
+
         if 'write' in dct and dct['write']:
             bases = tuple([SiteWriteMixin] + list(bases))
 
@@ -665,16 +732,19 @@
             interface = DrySite
 
         for data in cls.sites.values():
-            if 'site' not in data:
+            if 'site' not in data and 'code' in data and 'family' in data:
                 data['site'] = Site(data['code'], data['family'],
                                     interface=interface)
+            if 'hostname' not in data and 'site' in data:
+                data['hostname'] = data['site'].hostname()
 
         if not hasattr(cls, 'cached') or not cls.cached:
             pywikibot._sites = orig_sites
 
         if len(cls.sites) == 1:
             key = next(iter(cls.sites.keys()))
-            cls.site = cls.sites[key]['site']
+            if 'site' in cls.sites[key]:
+                cls.site = cls.sites[key]['site']
 
     @classmethod
     def get_site(cls, name=None):
@@ -830,19 +900,23 @@
         """
         super(WikibaseTestCase, cls).setUpClass()
 
-        for site in cls.sites.values():
-            if not site['site'].has_data_repository:
+        for data in cls.sites.values():
+            if 'site' not in data:
+                continue
+
+            site = data['site']
+            if not site.has_data_repository:
                 raise unittest.SkipTest(
                     u'%s: %r does not have data repository'
-                    % (cls.__name__, site['site']))
+                    % (cls.__name__, site))
 
             if (hasattr(cls, 'repo') and
-                    cls.repo != site['site'].data_repository()):
+                    cls.repo != site.data_repository()):
                 raise Exception(
                     '%s: sites do not all have the same data repository'
                     % cls.__name__)
 
-            cls.repo = site['site'].data_repository()
+            cls.repo = site.data_repository()
 
     @classmethod
     def get_repo(cls):
diff --git a/tests/data_ingestion_tests.py b/tests/data_ingestion_tests.py
index deec8a1..312bea0 100644
--- a/tests/data_ingestion_tests.py
+++ b/tests/data_ingestion_tests.py
@@ -14,7 +14,15 @@
 
     """Test Photo class."""
 
-    net = True
+    sites = {
+        'wm-upload': {
+            'hostname': 'upload.wikimedia.org',
+        },
+        'commons': {
+            'family': 'commons',
+            'code': 'commons',
+        },
+    }
 
     def setUp(self):
         super(TestPhoto, self).setUp()
@@ -28,11 +36,14 @@
                                         )
 
     def test_downloadPhoto(self):
+        """Test download from http://upload.wikimedia.org/.""";
         with open(os.path.join(_data_dir, 'MP_sounds.png'), 'rb') as f:
             self.assertEqual(f.read(), self.obj.downloadPhoto().read())
 
     def test_findDuplicateImages(self):
-        duplicates = self.obj.findDuplicateImages()
+        """Test finding duplicates on Wikimedia Commons."""
+        duplicates = self.obj.findDuplicateImages(
+            site=self.get_site('commons'))
         self.assertIn('MP sounds.png', [dup.replace("_", " ") for dup in 
duplicates])
 
     def test_getTitle(self):
diff --git a/tests/http_tests.py b/tests/http_tests.py
index 0263d62..9e9a3c7 100644
--- a/tests/http_tests.py
+++ b/tests/http_tests.py
@@ -27,10 +27,17 @@
 
     """Tests for http module."""
 
-    net = True
+    sites = {
+        'www-wp': {
+            'hostname': 'www.wikipedia.org',
+        },
+        'www-wq': {
+            'hostname': 'www.wikiquote.org',
+        },
+    }
 
     def test_async(self):
-        """Test http request_async function."""
+        """Test http._enqueue using http://www.wikipedia.org/.""";
         r = http._enqueue('http://www.wikipedia.org/')
         self.assertIsInstance(r, threadedhttp.HttpRequest)
         self.assertEqual(r.status, 200)
@@ -39,7 +46,7 @@
         self.assertIsInstance(r.raw, bytes)
 
     def test_fetch(self):
-        """Test http fetch function."""
+        """Test http.fetch using http://www.wikipedia.org/.""";
         r = http.fetch('http://www.wikipedia.org/')
         self.assertIsInstance(r, threadedhttp.HttpRequest)
         self.assertEqual(r.status, 200)
@@ -48,19 +55,49 @@
         self.assertIsInstance(r.raw, bytes)
 
     def test_http(self):
-        """Test http request function."""
+        """Test http.request using http://www.wikipedia.org/.""";
         r = http.request(site=None, uri='http://www.wikipedia.org/')
         self.assertIsInstance(r, unicode)
         self.assertIn('<html lang="mul"', r)
 
     def test_https(self):
-        """Test http request function using https."""
+        """Test http.request using https://www.wikiquote.org/.""";
         r = http.request(site=None, uri='https://www.wikiquote.org/')
         self.assertIsInstance(r, unicode)
         self.assertIn('<html lang="mul"', r)
 
+
+class HttpServerProblemTestCase(TestCase):
+
+    """Test HTTP status 502 causes this test class to be skipped."""
+
+    sites = {
+        '502': {
+            'hostname': 'http://getstatuscode.com/502',
+        }
+    }
+
+    def test_502(self):
+        """Test a HTTP 502 response using http://getstatuscode.com/502.""";
+        self.fail('The test framework should skip this test.')
+        pass
+
+
+class HttpsCertificateTestCase(TestCase):
+
+    """HTTPS certificate test."""
+
+    sites = {
+        'omegawiki': {
+            'hostname': 'www.omegawiki.org',
+        },
+        'vikidia': {
+            'hostname': 'en.vikidia.org',
+        },
+    }
+
     def test_https_cert_error(self):
-        """Test http request function fails on ssl bad certificate."""
+        """Test http.request fails on invalid omegawiki SSL certificate."""
         self.assertRaises(pywikibot.FatalServerError,
                           http.request,
                           site=None,
@@ -68,7 +105,7 @@
 
     @expectedFailureIf(sys.version_info[0] > 2)  # bug 72236
     def test_https_ignore_cert_error(self):
-        """Test http request function ignoring ssl bad certificate."""
+        """Test http.request ignoring invalid vikidia SSL certificate."""
         # As the connection is cached, the above test will cause
         # subsequent requests to go to the existing, broken, connection.
         # So, this uses a different host, which hopefully hasnt been
@@ -80,7 +117,7 @@
         self.assertIn('<title>Vikidia</title>', r)
 
     def test_https_cert_invalid(self):
-        """Verify certificate is bad."""
+        """Verify vikidia SSL certificate is invalid."""
         try:
             from pyasn1_modules import pem, rfc2459
             from pyasn1.codec.der import decoder
@@ -113,9 +150,17 @@
 
     """Tests for threadedhttp module Http class."""
 
-    net = True
+    sites = {
+        'www-wp': {
+            'hostname': 'www.wikipedia.org',
+        },
+        'wikidata': {
+            'hostname': 'test.wikidata.org',
+        },
+    }
 
     def test_http(self):
+        """Test threadedhttp.Http.request using http://www.wikipedia.org/.""";
         o = threadedhttp.Http()
         r = o.request('http://www.wikipedia.org/')
         self.assertIsInstance(r, tuple)
@@ -130,6 +175,7 @@
         self.assertEqual(int(r[0]['content-length']), len(r[1]))
 
     def test_https(self):
+        """Test threadedhttp.Http.request using https://www.wikipedia.org/.""";
         o = threadedhttp.Http()
         r = o.request('https://www.wikipedia.org/')
         self.assertIsInstance(r, tuple)
@@ -144,6 +190,7 @@
         self.assertEqual(int(r[0]['content-length']), len(r[1]))
 
     def test_gzip(self):
+        """Test threadedhttp.Http encodes using gzip."""
         o = threadedhttp.Http()
         r = o.request('http://www.wikipedia.org/')
         self.assertIsInstance(r, tuple)
@@ -159,11 +206,15 @@
         self.assertEqual(r[0]['-content-encoding'], 'gzip')
 
 
-class ThreadedHttpRequestTestCase(TestCase):
+class ThreadedHttpRequestQueueTestCase(TestCase):
 
     """Tests for threadedhttp module threaded HttpRequest."""
 
-    net = True
+    sites = {
+        'www-wp': {
+            'hostname': 'www.wikipedia.org',
+        },
+    }
 
     def test_threading(self):
         queue = Queue.Queue()
diff --git a/tests/interwiki_link_tests.py b/tests/interwiki_link_tests.py
index 61e8ae4..ea7ec08 100644
--- a/tests/interwiki_link_tests.py
+++ b/tests/interwiki_link_tests.py
@@ -66,6 +66,7 @@
     }
 
     def test_direct_non_local(self):
+        """Test translatewiki:Main Page on English Wikipedia."""
         link = Link('translatewiki:Main Page', self.get_site('wp'))
         link.parse()
         self.assertEqual(link.site, self.get_site('tw'))
@@ -73,6 +74,7 @@
         self.assertEqual(link.namespace, 0)
 
     def test_indirect_non_local(self):
+        """Test en:translatewiki:Main Page on English Wikipedia."""
         link = Link('en:translatewiki:Main Page', self.get_site('wp'))
         link.parse()
         self.assertEqual(link.site, self.get_site('tw'))
@@ -80,6 +82,7 @@
         self.assertEqual(link.namespace, 0)
 
     def test_via_local_non_local(self):
+        """Test de:translatewiki:Main Page on English Wikipedia."""
         link = Link('de:translatewiki:Main Page', self.get_site('wp'))
         self.assertRaisesRegex(
             InvalidTitle,
diff --git a/tests/weblib_tests.py b/tests/weblib_tests.py
index f4916e7..84f445f 100644
--- a/tests/weblib_tests.py
+++ b/tests/weblib_tests.py
@@ -7,7 +7,6 @@
 #
 __version__ = '$Id$'
 
-import os
 import sys
 if sys.version_info[0] > 2:
     from urllib.parse import urlparse
@@ -18,17 +17,15 @@
 from tests.aspects import unittest, TestCase
 
 
-class TestArchiveSites(TestCase):
+class TestInternetArchive(TestCase):
 
-    """Test weblib methods to access archive websites."""
+    """Test weblib methods to access Internet Archive."""
 
-    net = True
-
-    @classmethod
-    def setUpClass(cls):
-        if os.environ.get('TRAVIS', 'false') == 'true':
-            raise unittest.SkipTest('Weblib tests are disabled on Travis-CI')
-        super(TestArchiveSites, cls).setUpClass()
+    sites = {
+        'archive.org': {
+            'hostname': 'web.archive.org',
+        },
+    }
 
     def testInternetArchiveNewest(self):
         archivedversion = weblib.getInternetArchiveURL('https://google.com')
@@ -45,10 +42,23 @@
         self.assertTrue(parsed.path.strip('/').endswith('www.google.com'), 
parsed.path)
         self.assertIn('200606', parsed.path)
 
+
+class TestWebCite(TestCase):
+
+    """Test weblib methods to access WebCite."""
+
+    sites = {
+        'webcite': {
+            'hostname': 'www.webcitation.org',
+        }
+    }
+
+    @unittest.expectedFailure
     def testWebCiteOlder(self):
         archivedversion = weblib.getWebCitationURL('https://google.com', 
'20130101')
         self.assertEqual(archivedversion, 
'http://www.webcitation.org/6DHSeh2L0')
 
+
 if __name__ == '__main__':
     try:
         unittest.main()
diff --git a/tests/wikidataquery_tests.py b/tests/wikidataquery_tests.py
index 4c3b018..07822f0 100644
--- a/tests/wikidataquery_tests.py
+++ b/tests/wikidataquery_tests.py
@@ -19,9 +19,11 @@
 import time
 
 
-class TestApiFunctions(WikidataTestCase):
+class TestDryApiFunctions(TestCase):
 
     """Test WikiDataQuery API functions."""
+
+    net = False
 
     def testQueries(self):
         """
@@ -89,6 +91,13 @@
 
         q = query.HasClaim(99, query.Tree(1, [2, 5], [3, 90]))
         self.assertEqual(str(q), "claim[99:(tree[1][2,5][3,90])]")
+
+
+class TestLiveApiFunctions(WikidataTestCase):
+
+    """Test WikiDataQuery API functions."""
+
+    cached = True
 
     def testQueriesWDStructures(self):
         """Test queries using Wikibase page structures like ItemPage."""
@@ -217,7 +226,11 @@
 
     """Test slow WikiDataQuery API functions."""
 
-    net = True
+    sites = {
+        'wdq': {
+            'hostname': 'wdq.wmflabs.org',
+        },
+    }
 
     def testQueryApiGetter(self):
         """Test that we can actually retreive data and that caching works."""
diff --git a/tests/wikistats_tests.py b/tests/wikistats_tests.py
index c9e8532..deda834 100644
--- a/tests/wikistats_tests.py
+++ b/tests/wikistats_tests.py
@@ -22,7 +22,11 @@
 
     """Test WikiStats dump."""
 
-    net = True
+    sites = {
+        'wikistats': {
+            'hostname': 'wikistats.wmflabs.org',
+        },
+    }
 
     def test_sort(self):
         ws = WikiStats()

-- 
To view, visit https://gerrit.wikimedia.org/r/177985
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I8fdcdaa0fab3b680d35b81b20a12ff5b786f779d
Gerrit-PatchSet: 10
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: John Vandenberg <jay...@gmail.com>
Gerrit-Reviewer: John Vandenberg <jay...@gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgr...@gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhall...@arctus.nl>
Gerrit-Reviewer: XZise <commodorefabia...@gmx.de>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
Pywikibot-commits mailing list
Pywikibot-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/pywikibot-commits

Reply via email to