Skip to content

Commit

Permalink
Implement and use fake clients
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey Skripnick committed Dec 21, 2016
1 parent f707005 commit 993a258
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 13 deletions.
4 changes: 4 additions & 0 deletions ceagle/api/client.py
Expand Up @@ -16,11 +16,15 @@
import requests

from ceagle.api import base
from ceagle.api_fake_data import availability
from ceagle.api_fake_data import fake_security
from ceagle.api_fake_data import health
from ceagle import config

FAKE_CLIENT_MAP = {
"security": fake_security.Client,
"health": health.Client,
"availability": availability.Client,
}


Expand Down
2 changes: 0 additions & 2 deletions ceagle/api/v1/regions.py
Expand Up @@ -16,15 +16,13 @@
import flask

from ceagle.api import client
from ceagle.api_fake_data import fake_regions
from ceagle import config

bp = flask.Blueprint("regions", __name__)


@bp.route("", defaults={"detailed": False})
@bp.route("/detailed", defaults={"detailed": True})
@fake_regions.get_regions
def get_regions(detailed):
regions = {}

Expand Down
23 changes: 23 additions & 0 deletions ceagle/api_fake_data/availability.py
@@ -0,0 +1,23 @@
# Copyright 2016: Mirantis Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from ceagle.api_fake_data import base


class Client(base.FakeClient):

@base.route("/api/v1/availability/(?P<period>day|week|month)$")
def availability(self, query, period):
return {"availability": {}}, 200
68 changes: 67 additions & 1 deletion ceagle/api_fake_data/base.py
Expand Up @@ -15,11 +15,77 @@

import functools
import random
import re

from ceagle import config


USE_FAKE_DATA = config.get_config().get("use_fake_api_data", True)
FAKE_REGIONS = [
"west-1.hooli.net",
"north-1.piedpiper.net",
"east-1.hooli.net",
"south-1.piedpiper.net",
]


def route(reg):
def decorator(method):
method._route = re.compile(reg)
return method
return decorator


class BaseFakeClient(object):
"""Base fake client.
Usage:
>>> from ceagle.api_fake_data import base
>>> class MyClient(base.FakeClient):
... @base.route(r"/api/(?P<method>)")
... def _method(self, query, method):
... return {"query": query}, 200
...
>>> c = MyClient(name="name", endpoint="endpoint")
>>> resp, code = c.get("/api/foo", foo="bar")
>>> assert code == 200
>>> assert resp == {"query": {"foo": "bar"}}
"""

def __init__(self, name, endpoint):
self._setup_routing()

def _setup_routing(self):
self._routes = []
for attr in dir(self):
method = getattr(self, attr)
route = getattr(method, "_route", None)
if route:
self._routes.append((route, method))

def _find_route(self, path):
for reg, method in self._routes:
match = reg.match(path)
if match:
return method, match
return None, None

def default(self, path, *args, **kwargs):
return ("not found", 404)

def get(self, path, **kwargs):
method, match = self._find_route(path)
if method is None:
return self.default(path, **kwargs)
return method(kwargs, **match.groupdict())


class FakeClient(BaseFakeClient):

@route("/api/(?P<api>\w+)/regions")
def _regions(self, query, api):
return FAKE_REGIONS, 200


def api_handler(fake):
Expand Down
23 changes: 23 additions & 0 deletions ceagle/api_fake_data/health.py
@@ -0,0 +1,23 @@
# Copyright 2016: Mirantis Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from ceagle.api_fake_data import base


class Client(base.FakeClient):

@base.route("/api/v1/health/(?P<period>day|week|month)$")
def health(self, query, period):
return {"health": {}}, 200
23 changes: 23 additions & 0 deletions ceagle/api_fake_data/security.py
@@ -0,0 +1,23 @@
# Copyright 2016: Mirantis Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from ceagle.api_fake_data import base


class Client(base.FakeClient):

@base.route("/api/v1/security/issues/(?P<period>day|week|month)")
def health(self, query, period):
return {"issues": {}}, 200
4 changes: 3 additions & 1 deletion tests/ci/fake-clients-config.json
Expand Up @@ -5,6 +5,8 @@
"DEBUG": true
},
"services": {
"security": "http://example.org/api/security"
"security": "http://security.example.org/",
"health": "http://health.example.org/",
"availability": "http://availability.example.org/"
}
}
9 changes: 0 additions & 9 deletions tests/unit/api/v1/test_regions.py
Expand Up @@ -21,15 +21,6 @@
from tests.unit import test


class ApiTestCase(test.TestCase):

def test_api_response_code(self):
code, resp = self.get("/api/v1/regions")
self.assertEqual(code, 200)
code, resp = self.get("/api/v1/regions/detailed")
self.assertEqual(code, 200)


class RegionsApiTestCase(test.TestCase):

def setUp(self):
Expand Down

0 comments on commit 993a258

Please sign in to comment.