Skip to content

Commit 4691ad3

Browse files
authored
Merge pull request openshift#3 from detiber/testDocker
Fix up functional tests to use docker
2 parents ca77043 + 777c353 commit 4691ad3

17 files changed

+190
-80
lines changed

.coveragerc

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[run]
2+
branch = True
3+
omit =
4+
*/lib/python*/site-packages/*
5+
*/lib/python*/*
6+
/usr/*
7+
setup.py
8+
conftest.py
9+
openshift/test/*
10+
11+
[html]
12+
directory = cover

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ htmlcov/
4343
nosetests.xml
4444
coverage.xml
4545
*,cover
46+
cover/
4647
.hypothesis/
4748
venv/
4849
.python-version

.travis.yml

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
sudo: required
3+
4+
services:
5+
- docker
6+
7+
cache:
8+
- pip
9+
10+
language: python
11+
12+
python:
13+
- "2.7"
14+
- "3.5"
15+
16+
env:
17+
- OPENSHIFT_VERSION=latest
18+
- OPENSHIFT_VERSION=1.5
19+
- OPENSHIFT_VERSION=1.4
20+
- OPENSHIFT_VERSION=1.3
21+
22+
install:
23+
- pip install tox-travis coveralls
24+
25+
script:
26+
- tox
27+
28+
after_success:
29+
- coveralls
30+
31+
before_cache:
32+
- rm ~/.cache/pip/log/debug.log

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
# openshift-restclient-python
1+
# openshift-restclient-python
2+
3+
[![Build Status](https://travis-ci.org/openshift/openshift-restclient-python.svg?branch=master)](https://travis-ci.org/openshift/openshift-restclient-python)
4+
[![Coverage Status](https://coveralls.io/repos/github/openshift/openshift-restclient-python/badge.svg?branch=master)](https://coveralls.io/github/openshift/openshift-restclient-python?branch=master)

conftest.py

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
def pytest_addoption(parser):
2+
parser.addoption("--openshift-version", action="store", default="latest",
3+
help="Version of OpenShift to test against for functional tests")
4+
5+
6+
def pytest_report_header(config):
7+
return "OpenShift verison: {}".format(config.getoption('--openshift-version'))

openshift/ansiblegen/cli.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import logging
88
import sys
99

10+
from logging import config
11+
1012
from openshift import __version__
1113
from openshift.helper import OpenShiftException
1214

@@ -15,7 +17,6 @@
1517

1618
logger = logging.getLogger(__name__)
1719

18-
from logging import config
1920

2021
LOGGING = {
2122
'version': 1,
@@ -94,7 +95,7 @@ def run_docstrings_cmd(**kwargs):
9495
for model in models:
9596
try:
9697
strings = DocStrings(model=model, api_version=api_version)
97-
except OpenShiftException as exc:
98+
except OpenShiftException:
9899
raise
99100
print("DOCUMENTATION = '''")
100101
print(strings.documentation)

openshift/ansiblegen/docstrings.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def __init__(self, model, api_version):
2828
self.api_version = api_version
2929
try:
3030
self.helper = KubernetesObjectHelper(self.api_version, self.model)
31-
except OpenShiftException as exc:
31+
except OpenShiftException:
3232
raise
3333

3434
@property
@@ -46,7 +46,7 @@ def documentation(self):
4646
if not self.helper.base_model_name_snake.endswith('_list'):
4747
# module allows CRUD operations on the object
4848
doc_string['description'] = [
49-
"Manage the lifecycle of a {} object. Supports check mode, and attempts to " \
49+
"Manage the lifecycle of a {} object. Supports check mode, and attempts to "
5050
"to be idempotent.".format(self.helper.base_model_name_snake)
5151
]
5252
else:
@@ -155,7 +155,7 @@ def __get_attributes(self, obj, doc_key=None):
155155
sub_obj = None
156156
try:
157157
sub_obj = getattr(models, class_name)()
158-
except:
158+
except Exception:
159159
pass
160160
if sub_obj:
161161
doc_key[attribute]['contains'] = CommentedMap()
@@ -172,7 +172,7 @@ def __get_attributes(self, obj, doc_key=None):
172172
sub_obj = None
173173
try:
174174
sub_obj = getattr(models, class_name)()
175-
except:
175+
except Exception:
176176
pass
177177
if sub_obj:
178178
doc_key[attribute]['contains'] = CommentedMap()

openshift/ansiblegen/modules.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import logging
77
import inspect
88
import os
9-
import re
109
import shutil
1110
import string_utils
1211
import sys
@@ -89,7 +88,7 @@ def generate_modules(self):
8988
logger.debug("success!")
9089
except Exception as exc:
9190
logger.debug("failed!!")
92-
raise OpenShiftException(exc.message)
91+
raise OpenShiftException(str(exc))
9392

9493
context = {
9594
'documentation_string': documentation,
@@ -99,8 +98,8 @@ def generate_modules(self):
9998
}
10099
self.__jinja_render_to_temp('k8s_module.j2', module_name, temp_dir, **context)
101100
if not self.suppress_stdout:
102-
sys.stdout.write("\033[F") # cursor up 1 line
103-
sys.stdout.write("\033[K") # clear to EOL
101+
sys.stdout.write("\033[F") # cursor up 1 line
102+
sys.stdout.write("\033[K") # clear to EOL
104103
shutil.rmtree(temp_dir)
105104
if not self.suppress_stdout:
106105
print("Generated {} modules".format(len(self.models)))
@@ -133,6 +132,6 @@ def __create_output_path(self):
133132
raise OpenShiftException("ERROR: expected {} to be a directory.".format(self.output_path))
134133
else:
135134
try:
136-
os.makedirs(self.output_path, 0775)
135+
os.makedirs(self.output_path, 0o775)
137136
except os.error as exc:
138137
raise OpenShiftException("ERROR: could not create {0} - {1}".format(self.output_path, str(exc)))

openshift/helper/__init__.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ def get_object(self, name, namespace=None):
161161

162162
def patch_object(self, name, namespace, k8s_obj):
163163
# TODO: add a parameter for waiting until the object is ready
164-
k8s_obj.status = None
164+
empty_status = self.properties['status']['class']()
165+
k8s_obj.status = empty_status
165166
k8s_obj.metadata.resource_version = None
166167
try:
167168
patch_method = self.__lookup_method('patch', namespace)
@@ -458,7 +459,7 @@ def get_model(api_version, kind):
458459
model_name = api_version.capitalize() + name
459460
try:
460461
model = getattr(client.models, model_name)
461-
except Exception as exc:
462+
except Exception:
462463
raise OpenShiftException(
463464
"Error: openshift.client.models.{} was not found. "
464465
"Did you specify the correct Kind and API Version?".format(model_name)
@@ -586,7 +587,7 @@ def __log_argspec(self):
586587
tmp_arg_spec.pop(key)
587588
logger.debug(json.dumps(tmp_arg_spec, indent=4, sort_keys=True))
588589

589-
def __transform_properties(self, properties, prefix='', path=[], alternate_prefix=''):
590+
def __transform_properties(self, properties, prefix='', path=None, alternate_prefix=''):
590591
"""
591592
Convert a list of properties to an argument_spec dictionary
592593
@@ -596,6 +597,9 @@ def __transform_properties(self, properties, prefix='', path=[], alternate_prefi
596597
:param alternate_prefix: a more minimal version of prefix
597598
:return: dict
598599
"""
600+
if path is None:
601+
path = []
602+
599603
args = {}
600604
for prop, prop_attributes in properties.items():
601605
if prop in ('api_version', 'status', 'kind'):

openshift/test/functional/conftest.py

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import io
2+
import tarfile
3+
import time
4+
5+
import docker
6+
import pytest
7+
import requests
8+
9+
from six import StringIO
10+
11+
from kubernetes import config
12+
from openshift.helper import KubernetesObjectHelper
13+
14+
15+
@pytest.fixture(scope='session')
16+
def openshift_container(request):
17+
client = docker.from_env()
18+
# TODO: bind to a random host port
19+
image_name = 'openshift/origin:{}'.format(request.config.getoption('--openshift-version'))
20+
container = client.containers.run(image_name, 'start master', detach=True,
21+
ports={'8443/tcp': 8443})
22+
23+
try:
24+
# Wait for the container to no longer be in the created state before
25+
# continuing
26+
while container.status == u'created':
27+
time.sleep(0.2)
28+
container = client.containers.get(container.id)
29+
30+
# Wait for the api server to be ready before continuing
31+
# TODO: actually we end on a 200 response
32+
for _ in range(10):
33+
try:
34+
resp = requests.head("https://localhost:8443/healthz/ready", verify=False)
35+
if resp.status_code == 200:
36+
break
37+
except requests.RequestException:
38+
pass
39+
40+
time.sleep(1)
41+
42+
# TODO: handle waiting for system policy to be fully configured better
43+
time.sleep(1)
44+
45+
yield container
46+
finally:
47+
# Always remove the container
48+
container.remove(force=True)
49+
50+
51+
@pytest.fixture(scope='session')
52+
def kubeconfig(openshift_container, tmpdir_factory):
53+
# get_archive returns a stream of the tar archive containing the requested
54+
# files/directories, so we need use BytesIO as an intermediate step.
55+
tar_stream, _ = openshift_container.get_archive('/var/lib/origin/openshift.local.config/master/admin.kubeconfig')
56+
tar_obj = tarfile.open(fileobj=io.BytesIO(tar_stream.read()))
57+
kubeconfig_contents = tar_obj.extractfile('admin.kubeconfig').read()
58+
59+
kubeconfig_file = tmpdir_factory.mktemp('kubeconfig').join('admin.kubeconfig')
60+
kubeconfig_file.write(kubeconfig_contents)
61+
yield kubeconfig_file
62+
63+
64+
@pytest.fixture()
65+
def k8s_helper(request, kubeconfig):
66+
print(request.module.__name__)
67+
_,api_version,resource = request.module.__name__.split('_', 2)
68+
k8s_helper = KubernetesObjectHelper(api_version, resource)
69+
k8s_helper.set_client_config({'kubeconfig': str(kubeconfig)})
70+
config.kube_config.configuration.host='https://127.0.0.1:8443'
71+
yield k8s_helper

openshift/test/functional/test_v1_namespace.py

+4-11
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@
44

55
from openshift.helper import KubernetesObjectHelper
66

7-
pytestmark = pytest.mark.functional
8-
9-
@pytest.fixture(scope='module')
10-
def k8s_helper():
11-
k8s_helper = KubernetesObjectHelper('v1', 'namespace')
12-
return k8s_helper
13-
147

158
@pytest.fixture()
169
def namespace(k8s_helper):
@@ -24,7 +17,7 @@ def namespace(k8s_helper):
2417

2518
yield namespace
2619

27-
k8s_helper.delete_object(name)
20+
k8s_helper.delete_object(name, None)
2821

2922

3023
def test_namespace_patch(k8s_helper, namespace):
@@ -41,10 +34,10 @@ def test_namespace_exists(k8s_helper, namespace):
4134
get_result = k8s_helper.get_object(namespace.metadata.name)
4235
assert get_result is not None
4336
assert get_result.metadata.name == namespace.metadata.name
44-
assert get_result == namespace
37+
assert get_result.metadata.uid == namespace.metadata.uid
4538

4639

4740
def test_get_exists_not(k8s_helper):
4841
name = "does-not-exist-{}".format(uuid.uuid4())
49-
namespace = k8s_helper.get_object(name)
50-
assert namespace is None
42+
result = k8s_helper.get_object(name)
43+
assert result is None

openshift/test/functional/test_v1_project.py

+3-10
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@
44

55
from openshift.helper import KubernetesObjectHelper
66

7-
pytestmark = pytest.mark.functional
8-
9-
@pytest.fixture(scope='module')
10-
def k8s_helper():
11-
k8s_helper = KubernetesObjectHelper('v1', 'project')
12-
return k8s_helper
13-
147

158
@pytest.fixture()
169
def project(k8s_helper):
@@ -24,10 +17,10 @@ def project(k8s_helper):
2417

2518
yield project
2619

27-
k8s_helper.delete_object(name)
20+
k8s_helper.delete_object(name, None)
2821

2922

30-
@pytest.mark.skip()
23+
@pytest.mark.skip(reason="project fields are immutable")
3124
def test_project_patch(k8s_helper, project):
3225
ns_copy = copy.deepcopy(project)
3326
ns_copy.metadata.labels = {'test-label': 'test-value'}
@@ -42,7 +35,7 @@ def test_project_exists(k8s_helper, project):
4235
get_result = k8s_helper.get_object(project.metadata.name)
4336
assert get_result is not None
4437
assert get_result.metadata.name == project.metadata.name
45-
assert get_result == project
38+
assert get_result.metadata.uid == project.metadata.uid
4639

4740

4841
def test_get_exists_not(k8s_helper):

requirements.txt

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
urllib3>=1.19
2-
six>=1.10
3-
kubernetes
4-
certifi
5-
python-dateutil
6-
pyyaml
7-
oauth2client
8-
ipaddress
1+
kubernetes >= 1.0.0b3
92
python-string-utils
103
ruamel.yaml
114
jinja2

setup.cfg

+11
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,14 @@ max_line_length = 120
1313
[yapf]
1414
based_on_style = pep8
1515
dedent_closing_brackets = True
16+
17+
[tool:pytest]
18+
norecursedirs =
19+
.*
20+
__pycache__
21+
cover
22+
docs
23+
addopts =
24+
--cov=openshift
25+
--cov-report=term
26+
--cov-report=html

test-requirements.txt

+5-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
git+https://github.com/detiber/client-python@master
1+
coverage
2+
docker ~= 2.1.0
3+
flake8
4+
pytest
5+
pytest-cov

test_helper.py

-7
This file was deleted.

0 commit comments

Comments
 (0)