Skip to content

Commit

Permalink
move core testserver into tests
Browse files Browse the repository at this point in the history
  • Loading branch information
iscai-msft committed Jun 24, 2021
1 parent 8ccce34 commit 30c6e39
Show file tree
Hide file tree
Showing 12 changed files with 489 additions and 1 deletion.
2 changes: 1 addition & 1 deletion sdk/core/azure-core/dev_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ opencensus-ext-threading
mock; python_version < '3.3'
-e ../../../tools/azure-sdk-tools
-e ../../../tools/azure-devtools
git+https://github.com/iscai-msft/core.testserver#subdirectory=coretestserver
-e tests/testserver_tests/coretestserver
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# coding: utf-8
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE.txt in the project root for
# license information.
# -------------------------------------------------------------------------

from flask import Flask, Response
from .test_routes import (
basic_api,
encoding_api,
errors_api,
streams_api,
urlencoded_api,
multipart_api,
xml_api
)

app = Flask(__name__)
app.register_blueprint(basic_api, url_prefix="/basic")
app.register_blueprint(encoding_api, url_prefix="/encoding")
app.register_blueprint(errors_api, url_prefix="/errors")
app.register_blueprint(streams_api, url_prefix="/streams")
app.register_blueprint(urlencoded_api, url_prefix="/urlencoded")
app.register_blueprint(multipart_api, url_prefix="/multipart")
app.register_blueprint(xml_api, url_prefix="/xml")

@app.route('/health', methods=['GET'])
def latin_1_charset_utf8():
return Response(status=200)

if __name__ == "__main__":
app.run(debug=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# coding: utf-8
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE.txt in the project root for
# license information.
# -------------------------------------------------------------------------

from .basic import basic_api
from .encoding import encoding_api
from .errors import errors_api
from .multipart import multipart_api
from .streams import streams_api
from .urlencoded import urlencoded_api
from .xml_route import xml_api

__all__ = [
"basic_api",
"encoding_api",
"errors_api",
"multipart_api",
"streams_api",
"urlencoded_api",
"xml_api",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# coding: utf-8
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE.txt in the project root for
# license information.
# -------------------------------------------------------------------------

from flask import (
Response,
Blueprint,
request
)

basic_api = Blueprint('basic_api', __name__)

@basic_api.route('/string', methods=['GET'])
def string():
return Response(
"Hello, world!", status=200, mimetype="text/plain"
)

@basic_api.route('/lines', methods=['GET'])
def lines():
return Response(
"Hello,\nworld!", status=200, mimetype="text/plain"
)

@basic_api.route("/bytes", methods=['GET'])
def bytes():
return Response(
"Hello, world!".encode(), status=200, mimetype="text/plain"
)

@basic_api.route("/html", methods=['GET'])
def html():
return Response(
"<html><body>Hello, world!</html></body>", status=200, mimetype="text/html"
)

@basic_api.route("/json", methods=['GET'])
def json():
return Response(
'{"greeting": "hello", "recipient": "world"}', status=200, mimetype="application/json"
)

@basic_api.route("/complicated-json", methods=['POST'])
def complicated_json():
# thanks to Sean Kane for this test!
assert request.json['EmptyByte'] == ''
assert request.json['EmptyUnicode'] == ''
assert request.json['SpacesOnlyByte'] == ' '
assert request.json['SpacesOnlyUnicode'] == ' '
assert request.json['SpacesBeforeByte'] == ' Text'
assert request.json['SpacesBeforeUnicode'] == ' Text'
assert request.json['SpacesAfterByte'] == 'Text '
assert request.json['SpacesAfterUnicode'] == 'Text '
assert request.json['SpacesBeforeAndAfterByte'] == ' Text '
assert request.json['SpacesBeforeAndAfterUnicode'] == ' Text '
assert request.json['啊齄丂狛'] == 'ꀕ'
assert request.json['RowKey'] == 'test2'
assert request.json['啊齄丂狛狜'] == 'hello'
assert request.json["singlequote"] == "a''''b"
assert request.json["doublequote"] == 'a""""b'
assert request.json["None"] == None

return Response(status=200)
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# coding: utf-8
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE.txt in the project root for
# license information.
# -------------------------------------------------------------------------
from json import dumps
from flask import (
Response,
Blueprint,
)

encoding_api = Blueprint('encoding_api', __name__)

@encoding_api.route('/latin-1', methods=['GET'])
def latin_1():
r = Response(
"Latin 1: ÿ".encode("latin-1"), status=200
)
r.headers["Content-Type"] = "text/plain; charset=latin-1"
return r

@encoding_api.route('/latin-1-with-utf-8', methods=['GET'])
def latin_1_charset_utf8():
r = Response(
"Latin 1: ÿ".encode("latin-1"), status=200
)
r.headers["Content-Type"] = "text/plain; charset=utf-8"
return r

@encoding_api.route('/no-charset', methods=['GET'])
def latin_1_no_charset():
r = Response(
"Hello, world!", status=200
)
r.headers["Content-Type"] = "text/plain"
return r

@encoding_api.route('/iso-8859-1', methods=['GET'])
def iso_8859_1():
r = Response(
"Accented: Österreich".encode("iso-8859-1"), status=200
)
r.headers["Content-Type"] = "text/plain"
return r

@encoding_api.route('/emoji', methods=['GET'])
def emoji():
r = Response(
"👩", status=200
)
return r

@encoding_api.route('/emoji-family-skin-tone-modifier', methods=['GET'])
def emoji_family_skin_tone_modifier():
r = Response(
"👩🏻‍👩🏽‍👧🏾‍👦🏿 SSN: 859-98-0987", status=200
)
return r

@encoding_api.route('/korean', methods=['GET'])
def korean():
r = Response(
"아가", status=200
)
return r

@encoding_api.route('/json', methods=['GET'])
def json():
data = {"greeting": "hello", "recipient": "world"}
content = dumps(data).encode("utf-16")
r = Response(
content, status=200
)
r.headers["Content-Type"] = "application/json; charset=utf-16"
return r

@encoding_api.route('/invalid-codec-name', methods=['GET'])
def invalid_codec_name():
r = Response(
"おはようございます。".encode("utf-8"), status=200
)
r.headers["Content-Type"] = "text/plain; charset=invalid-codec-name"
return r

@encoding_api.route('/no-charset', methods=['GET'])
def no_charset():
r = Response(
"Hello, world!", status=200
)
r.headers["Content-Type"] = "text/plain"
return r
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# coding: utf-8
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE.txt in the project root for
# license information.
# -------------------------------------------------------------------------
from flask import (
Response,
Blueprint,
)

errors_api = Blueprint('errors_api', __name__)

@errors_api.route('/403', methods=['GET'])
def get_403():
return Response(status=403)

@errors_api.route('/500', methods=['GET'])
def get_500():
return Response(status=500)

@errors_api.route('/stream', methods=['GET'])
def get_stream():
class StreamingBody:
def __iter__(self):
yield b"Hello, "
yield b"world!"
return Response(StreamingBody(), status=500)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE.txt in the project root for
# license information.
# -------------------------------------------------------------------------

def assert_with_message(param_name, expected_value, actual_value):
assert expected_value == actual_value, "Expected '{}' to be '{}', got '{}'".format(
param_name, expected_value, actual_value
)

__all__ = ["assert_with_message"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# coding: utf-8
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE.txt in the project root for
# license information.
# -------------------------------------------------------------------------
from copy import copy
from flask import (
Response,
Blueprint,
request,
)
from .helpers import assert_with_message

multipart_api = Blueprint('multipart_api', __name__)

multipart_header_start = "multipart/form-data; boundary="

# NOTE: the flask behavior is different for aiohttp and requests
# in requests, we see the file content through request.form
# in aiohttp, we see the file through request.files

@multipart_api.route('/basic', methods=['POST'])
def basic():
assert_with_message("content type", multipart_header_start, request.content_type[:len(multipart_header_start)])
if request.files:
# aiohttp
assert_with_message("content length", 258, request.content_length)
assert_with_message("num files", 1, len(request.files))
assert_with_message("has file named fileContent", True, bool(request.files.get('fileContent')))
file_content = request.files['fileContent']
assert_with_message("file content type", "application/octet-stream", file_content.content_type)
assert_with_message("file content length", 14, file_content.content_length)
assert_with_message("filename", "fileContent", file_content.filename)
assert_with_message("has content disposition header", True, bool(file_content.headers.get("Content-Disposition")))
assert_with_message(
"content disposition",
'form-data; name="fileContent"; filename="fileContent"; filename*=utf-8\'\'fileContent',
file_content.headers["Content-Disposition"]
)
elif request.form:
# requests
assert_with_message("content length", 184, request.content_length)
assert_with_message("fileContent", "<file content>", request.form["fileContent"])
else:
return Response(status=400) # should be either of these
return Response(status=200)

@multipart_api.route('/data-and-files', methods=['POST'])
def data_and_files():
assert_with_message("content type", multipart_header_start, request.content_type[:len(multipart_header_start)])
assert_with_message("message", "Hello, world!", request.form["message"])
assert_with_message("message", "<file content>", request.form["fileContent"])
return Response(status=200)

@multipart_api.route('/data-and-files-tuple', methods=['POST'])
def data_and_files_tuple():
assert_with_message("content type", multipart_header_start, request.content_type[:len(multipart_header_start)])
assert_with_message("message", ["abc"], request.form["message"])
assert_with_message("message", ["<file content>"], request.form["fileContent"])
return Response(status=200)

@multipart_api.route('/non-seekable-filelike', methods=['POST'])
def non_seekable_filelike():
assert_with_message("content type", multipart_header_start, request.content_type[:len(multipart_header_start)])
if request.files:
# aiohttp
len_files = len(request.files)
assert_with_message("num files", 1, len_files)
# assert_with_message("content length", 258, request.content_length)
assert_with_message("num files", 1, len(request.files))
assert_with_message("has file named file", True, bool(request.files.get('file')))
file = request.files['file']
assert_with_message("file content type", "application/octet-stream", file.content_type)
assert_with_message("file content length", 14, file.content_length)
assert_with_message("filename", "file", file.filename)
assert_with_message("has content disposition header", True, bool(file.headers.get("Content-Disposition")))
assert_with_message(
"content disposition",
'form-data; name="fileContent"; filename="fileContent"; filename*=utf-8\'\'fileContent',
file.headers["Content-Disposition"]
)
elif request.form:
# requests
assert_with_message("num files", 1, len(request.form))
else:
return Response(status=400)
return Response(status=200)
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# coding: utf-8
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE.txt in the project root for
# license information.
# -------------------------------------------------------------------------
from flask import (
Response,
Blueprint,
)

streams_api = Blueprint('streams_api', __name__)

class StreamingBody:
def __iter__(self):
yield b"Hello, "
yield b"world!"


def streaming_body():
yield b"Hello, "
yield b"world!"

def stream_json_error():
yield '{"error": {"code": "BadRequest", '
yield' "message": "You made a bad request"}}'

@streams_api.route('/basic', methods=['GET'])
def basic():
return Response(streaming_body(), status=200)

@streams_api.route('/iterable', methods=['GET'])
def iterable():
return Response(StreamingBody(), status=200)

@streams_api.route('/error', methods=['GET'])
def error():
return Response(stream_json_error(), status=400)
Loading

0 comments on commit 30c6e39

Please sign in to comment.