Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

ensure correct value type in data field of Request object in Python 2/3 #2806

Merged
merged 2 commits into from Mar 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion easybuild/base/rest.py
Expand Up @@ -39,7 +39,7 @@
from functools import partial

from easybuild.base import fancylogger
from easybuild.tools.py2vs3 import HTTPSHandler, Request, build_opener, json_loads, urlencode
from easybuild.tools.py2vs3 import HTTPSHandler, Request, build_opener, json_loads, string_type, urlencode


class Client(object):
Expand Down Expand Up @@ -193,6 +193,13 @@ def get_connection(self, method, url, body, headers):
sep = '/'
else:
sep = ''

# value passed to 'data' must be a 'bytes' value (not 'str') in Python 3.x, but a string value in Python 2
# hence, we encode the value obtained (if needed)
# this doesn't affect the value type in Python 2, and makes it a 'bytes' value in Python 3
if isinstance(body, string_type):
body = body.encode('utf-8')

request = Request(self.url + sep + url, data=body)
for header, value in headers.items():
request.add_header(header, value)
Expand Down
39 changes: 38 additions & 1 deletion test/framework/github.py
Expand Up @@ -28,18 +28,20 @@
@author: Jens Timmerman (Ghent University)
@author: Kenneth Hoste (Ghent University)
"""
import base64
import os
import random
import re
import sys
from test.framework.utilities import EnhancedTestCase, TestLoaderFiltered, init_config
from unittest import TextTestRunner

from easybuild.base.rest import RestClient
from easybuild.tools.build_log import EasyBuildError
from easybuild.tools.config import module_classes
from easybuild.tools.configobj import ConfigObj
from easybuild.tools.filetools import read_file, write_file
from easybuild.tools.py2vs3 import URLError, ascii_letters
from easybuild.tools.py2vs3 import HTTPError, URLError, ascii_letters
import easybuild.tools.github as gh

try:
Expand Down Expand Up @@ -551,6 +553,41 @@ def test_det_patch_specs(self):
self.assertEqual(os.path.basename(res[2][0]), '3.patch')
self.assertEqual(res[2][1], 'C')

def test_restclient(self):
"""Test use of RestClient."""
if self.skip_github_tests:
print("Skipping test_restclient, no GitHub token available?")
return

client = RestClient('https://api.github.com', username=GITHUB_TEST_ACCOUNT, token=self.github_token)

status, body = client.repos['hpcugent']['testrepository'].contents.a_directory['a_file.txt'].get()
self.assertEqual(status, 200)
# base64.b64encode requires & produces a 'bytes' value in Python 3,
# but we need a string value hence the .decode() (also works in Python 2)
self.assertEqual(body['content'].strip(), base64.b64encode(b'this is a line of text\n').decode())

status, headers = client.head()
self.assertEqual(status, 200)
self.assertTrue(headers)
self.assertTrue('X-GitHub-Media-Type' in headers)

httperror_hit = False
try:
status, body = client.user.emails.post(body='test@example.com')
self.assertTrue(False, 'posting to unauthorized endpoint did not throw a http error')
except HTTPError:
httperror_hit = True
self.assertTrue(httperror_hit, "expected HTTPError not encountered")

httperror_hit = False
try:
status, body = client.user.emails.delete(body='test@example.com')
self.assertTrue(False, 'deleting to unauthorized endpoint did not throw a http error')
except HTTPError:
httperror_hit = True
self.assertTrue(httperror_hit, "expected HTTPError not encountered")


def suite():
""" returns all the testcases in this module """
Expand Down