Skip to content

Commit 44fe5cc

Browse files
authored
Improve acceptance testing & fix bug when project id is empty (#12)
ENHANCEMENT: - Add test scenario and improve the testing framework - Improve continuous deployment workflow, integration on a private cluster BUGFIX: - Fix unexpected error when project id is empty
1 parent 42e38e3 commit 44fe5cc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+15434
-3085
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ coverage.xml
4646
*.cover
4747
.hypothesis/
4848
.pytest_cache/
49+
.allure/
4950

5051
# Translations
5152
*.mo

.travis.yml

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,3 @@ script:
1818

1919
after_success:
2020
- bash <(curl -s https://codecov.io/bash)
21-
22-
before_deploy:
23-
- make docs
24-
- touch docs/build/html/.nojekyll
25-
26-
# deploy new versions to PyPI / GithubIO
27-
deploy:
28-
- provider: pages
29-
skip_cleanup: true
30-
github_token:
31-
secure: "6QeIhg8F4Ztr+u4C7KuwmsiinglEBwjSafN/QYVf4pmJ6Jn5HzJSbZYPsHhqkDS0HbrJr4IOYkTL9ezeKif1Jd8lQ2ZrtTrKxvWiuO2EysF2hk0j0nDbYsaGct+Aam5M1mr2EVU6mwrr34sivs6pn6ZcpMNcpPHWMDIg5+2WyOspP9mWDFGTcOapvtky8SKpmpffmRnOcrsziYKEgDv/s9zJrP4IJ9CoICvMdgQMNb7OfIhNNBow6UOV7gkczOajFLCSmO/cFOyO5D/V/B+6DCUaYLlFr/az224+KSflkB7WWtEouJ+hlLV0T9XyabmZG+pp8jutgBnygXBwVMFj29AfCC0fCuZzXoQofYZNnLPpGUxdDQpZrDhMe85D3dXS+2FT8zc8bJ5Sdr7K8b70xLrZunzSxGT9LBa5riN+rqsB3laSEk4j5+WGye4U2RIsak3jTe4Hr3MnPIS/Xaof/2bn7ikInLa5W98KVUHbIute0B2FpZkOl0u4NatPrZJHUVhYII7m4jnZzoOCDWRpV09okwkHtLaGE7ekNTIa2Qgdbj6gdJ5kYl6kngT+3hYOVmz6txCHB7sfZhizl/wq1zf2YU6gL2JiSg8noYuLd/Fasulu9cpogjrvj/TPAw1W4vSk9CMwEU8REiCyU5lrCK2FJPKQeH/h0wXZ3kPhGGo="
32-
local_dir: docs/build/html
33-
on:
34-
branch: master
35-
repo: ucloud/ucloud-sdk-python3
36-
python: 3.7
37-
- provider: pypi
38-
distributions: sdist bdist_wheel
39-
skip_existing: true
40-
user: ucloud
41-
password:
42-
secure: "IVZJgV6z5wYb53RP1XNIO4aOedbdlSCGNSKfnMVugmeVFCLoBZsT99FeRzmQ8xFUU6PBSL4avX1QBgzYBIKqksTMVR4bFDha+Nw4NChy/XK7AEsGXnzyb8usnzqx4GzopDGZWqY8mNAd4UVsrmhcdYozKU8ZdSAg/H5zm/yx2Jnv8mcjFrdC11Mv+qtHbNLADvNwV6mACNvPr9jAVtkoYSLZ+mOEc6ZoORgxhcpnZXSb2ABnC/7BvCqqnlrDYNftMFF21lX7xHsA+il0xkWMrrsapWSueW4y1wWt5WksfOjFL2F0fbkS18CMYoIqCyk0A6BVkvqR0n9JUFwA9Zz1bikf4ZdMsQyLcjb9l5Xfc4+ij22oevrnQ0A90lgZi8foiCRiMGAiKyxY91pEAfrSEj+TWqqWlHAv6HPKU+975dSkQIZHhlL0cyqxx0Zl/SvcQ1deGyuXnME4VJm6fyoq+aI47Yg8ZFGuwGbJyCVZrsA+8thDUHTf5BNlMMIqQn8RYoHOsAIpgkVzcHa2Ko/kQRcTrhYoUIN9EoR4wuxjFhW1UGRe8khazT4qu9jIpT7TnuWX5xxHL+ZRTaiwMr5ZU79WVvnYNZymKLMWQ0ExVsIix+Z8BwO+pK9FyQ8mMgVWdCJDepVDZgcSdikd4+i81UfJkF71bu50Y7el/rqrOrA="
43-
on:
44-
branch: master
45-
tags: true
46-
repo: ucloud/ucloud-sdk-python3
47-
python: 3.7

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ lint:
4747
@flake8 --exclude=ucloud/services ucloud --ignore=E501,F401
4848

4949
fmt:
50-
@black -l 80 ucloud tests
50+
@black -l 80 ucloud tests examples
5151

5252
dev:
5353
@pip install -e .[dev]

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<img src="https://ucloud-sdk.dl.ufileos.com/logos%2Flogo-mini.png" />
33
</p>
44

5-
<h1 align="center">UCloud Go Python3</h1>
5+
<h1 align="center">UCloud SDK Python 3</h1>
66

77
<p align="center">
88
<a href="https://pypi.python.org/pypi/ucloud-sdk-python3/"><img src="https://img.shields.io/pypi/v/ucloud-sdk-python3.svg" alt="Latest Stable Version"></a>
@@ -13,8 +13,8 @@
1313

1414
UCloud SDK is a Python client library for accessing the UCloud API.
1515

16-
This client can run on Linux, macOS and Windows. It requires Python 3.5 and above.
16+
This client can run on Linux, macOS and Windows.
1717

1818
- Website: https://www.ucloud.cn/
1919
- Free software: Apache 2.0 license
20-
- `Documentation <https://ucloud.github.io/ucloud-sdk-python3/>`_
20+
- [Documentation](https://ucloud.github.io/ucloud-sdk-python3/)

docs/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ UCloud SDK Python 3
33

44
UCloud SDK is a Python client library for accessing the UCloud API.
55

6-
This client can run on Linux, macOS and Windows. It requires Python 3.5 and above.
6+
This client can run on Linux, macOS and Windows.
77

88
- Website: https://www.ucloud.cn/
99
- Free software: Apache 2.0 license

examples/debug/__init__.py

Whitespace-only changes.

examples/two-tier/main.py

Lines changed: 67 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@
55
from ucloud.client import Client
66
from ucloud.helpers import wait, utils
77

8-
logger = logging.getLogger('ucloud')
8+
logger = logging.getLogger("ucloud")
99
logger.setLevel(logging.DEBUG)
1010

1111
# NOTE: find your public/private key at
1212
# website `UAPI <https://console.ucloud.cn/uapi/apikey>`_
13-
client = Client({
14-
"region": "cn-bj2",
15-
"project_id": os.getenv("UCLOUD_PROJECT_ID"),
16-
"public_key": os.getenv("UCLOUD_PUBLIC_KEY"),
17-
"private_key": os.getenv("UCLOUD_PRIVATE_KEY"),
18-
})
13+
client = Client(
14+
{
15+
"region": "cn-bj2",
16+
"project_id": os.getenv("UCLOUD_PROJECT_ID"),
17+
"public_key": os.getenv("UCLOUD_PUBLIC_KEY"),
18+
"private_key": os.getenv("UCLOUD_PRIVATE_KEY"),
19+
}
20+
)
1921

2022

2123
def main():
@@ -39,98 +41,111 @@ def main():
3941

4042

4143
def describe_image():
42-
images = client.uhost().describe_image({'ImageType': 'Base'}).get('ImageSet', [])
44+
images = (
45+
client.uhost().describe_image({"ImageType": "Base"}).get("ImageSet", [])
46+
)
4347
if not images:
4448
return
4549
image = random.choice(images)
46-
return image.get('ImageId')
50+
return image.get("ImageId")
4751

4852

4953
def mget_uhost_states(uhost_ids):
50-
resp = client.uhost().describe_uhost_instance({'UHostIds': uhost_ids})
51-
return [inst.get('State') for inst in resp.get('UHostSet')]
54+
resp = client.uhost().describe_uhost_instance({"UHostIds": uhost_ids})
55+
return [inst.get("State") for inst in resp.get("UHostSet")]
5256

5357

5458
def create_uhost_batch(image_id, count):
55-
resp = client.uhost().create_uhost_instance({
56-
'Name': 'sdk-python3-example-two-tier',
57-
'Zone': 'cn-bj2-05',
58-
'ImageId': image_id,
59-
'LoginMode': "Password",
60-
'Password': utils.gen_password(20),
61-
'CPU': 1,
62-
'Memory': 1024,
63-
'MaxCount': count,
64-
})
65-
uhost_ids = resp.get('UHostIds', [])
59+
resp = client.uhost().create_uhost_instance(
60+
{
61+
"Name": "sdk-python3-example-two-tier",
62+
"Zone": "cn-bj2-05",
63+
"ImageId": image_id,
64+
"LoginMode": "Password",
65+
"Password": utils.gen_password(20),
66+
"CPU": 1,
67+
"Memory": 1024,
68+
"MaxCount": count,
69+
}
70+
)
71+
uhost_ids = resp.get("UHostIds", [])
6672
wait.wait_for_state(
67-
target=['running'], pending=['pending'], timeout=300,
73+
target=["running"],
74+
pending=["pending"],
75+
timeout=300,
6876
refresh=lambda: (
69-
'running' if all([state == 'Running' for state in mget_uhost_states(uhost_ids)]) else 'pending'
77+
"running"
78+
if all(
79+
[state == "Running" for state in mget_uhost_states(uhost_ids)]
80+
)
81+
else "pending"
7082
),
7183
)
7284
return uhost_ids
7385

7486

7587
def create_ulb():
76-
resp = client.ulb().create_ulb({
77-
'Name': 'sdk-python3-example-two-tier',
78-
})
79-
return resp.get('ULBId')
88+
resp = client.ulb().create_ulb({"Name": "sdk-python3-example-two-tier"})
89+
return resp.get("ULBId")
8090

8191

8292
def create_vserver(ulb_id):
83-
resp = client.ulb().create_vserver({
84-
'Name': 'sdk-python3-example-two-tier',
85-
'ULBId': ulb_id,
86-
})
87-
return resp.get('VServerId')
93+
resp = client.ulb().create_vserver(
94+
{"Name": "sdk-python3-example-two-tier", "ULBId": ulb_id}
95+
)
96+
return resp.get("VServerId")
8897

8998

9099
def allocate_backend_batch(ulb_id, vserver_id, uhost_ids):
91100
backend_ids = []
92101
for uhost_id in uhost_ids:
93-
resp = client.ulb().allocate_backend({
94-
'ULBId': ulb_id,
95-
'VServerId': vserver_id,
96-
'ResourceId': uhost_id,
97-
'ResourceType': 'UHost',
98-
})
99-
backend_ids.append(resp.get('BackendId'))
102+
resp = client.ulb().allocate_backend(
103+
{
104+
"ULBId": ulb_id,
105+
"VServerId": vserver_id,
106+
"ResourceId": uhost_id,
107+
"ResourceType": "UHost",
108+
}
109+
)
110+
backend_ids.append(resp.get("BackendId"))
100111
return backend_ids
101112

102113

103114
def release_backend_batch(ulb_id, vserver_id, backend_ids):
104115
for backend_id in backend_ids:
105-
client.ulb().release_backend({
106-
'ULBId': ulb_id,
107-
'VServerId': vserver_id,
108-
'BackendId': backend_id,
109-
})
116+
client.ulb().release_backend(
117+
{"ULBId": ulb_id, "VServerId": vserver_id, "BackendId": backend_id}
118+
)
110119

111120

112121
def delete_vserver(ulb_id, vserver_id):
113-
client.ulb().delete_vserver({'ULBId': ulb_id, 'VServerId': vserver_id})
122+
client.ulb().delete_vserver({"ULBId": ulb_id, "VServerId": vserver_id})
114123

115124

116125
def delete_ulb(ulb_id):
117-
client.ulb().delete_ulb({'ULBId': ulb_id})
126+
client.ulb().delete_ulb({"ULBId": ulb_id})
118127

119128

120129
def delete_uhost_batch(uhost_ids):
121130
for uhost_id in uhost_ids:
122-
client.uhost().stop_uhost_instance({'UHostId': uhost_id})
131+
client.uhost().stop_uhost_instance({"UHostId": uhost_id})
123132

124133
wait.wait_for_state(
125-
target=['stopped'], pending=['pending'], timeout=300,
134+
target=["stopped"],
135+
pending=["pending"],
136+
timeout=300,
126137
refresh=lambda: (
127-
'stopped' if all([state == 'Stopped' for state in mget_uhost_states(uhost_ids)]) else 'pending'
138+
"stopped"
139+
if all(
140+
[state == "Stopped" for state in mget_uhost_states(uhost_ids)]
141+
)
142+
else "pending"
128143
),
129144
)
130145

131146
for uhost_id in uhost_ids:
132-
client.uhost().terminate_uhost_instance({'UHostId': uhost_id})
147+
client.uhost().terminate_uhost_instance({"UHostId": uhost_id})
133148

134149

135-
if __name__ == '__main__':
150+
if __name__ == "__main__":
136151
main()

examples/uhost/main.py

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,71 +5,93 @@
55
from ucloud.client import Client
66
from ucloud.helpers import wait, utils
77

8-
logger = logging.getLogger('ucloud')
8+
logger = logging.getLogger("ucloud")
99
logger.setLevel(logging.DEBUG)
1010

1111

1212
def main():
13-
client = Client({
14-
"region": "cn-bj2",
15-
"project_id": os.getenv("UCLOUD_PROJECT_ID"),
16-
"public_key": os.getenv("UCLOUD_PUBLIC_KEY"),
17-
"private_key": os.getenv("UCLOUD_PRIVATE_KEY"),
18-
})
13+
client = Client(
14+
{
15+
"region": "cn-bj2",
16+
"project_id": os.getenv("UCLOUD_PROJECT_ID"),
17+
"public_key": os.getenv("UCLOUD_PUBLIC_KEY"),
18+
"private_key": os.getenv("UCLOUD_PRIVATE_KEY"),
19+
}
20+
)
1921

2022
logger.info("finding image, random choice one")
21-
images = client.uhost().describe_image({
22-
'ImageType': 'Base', 'OsType': 'Linux'
23-
}).get('ImageSet', [])
23+
images = (
24+
client.uhost()
25+
.describe_image({"ImageType": "Base", "OsType": "Linux"})
26+
.get("ImageSet", [])
27+
)
2428

2529
assert len(images) > 0
2630

2731
logger.info("creating uhost instance ...")
2832
image = random.choice(images)
2933

30-
resp = client.uhost().create_uhost_instance({
31-
'Name': 'sdk-python-example',
32-
'Zone': image["Zone"],
33-
'ImageId': image["ImageId"],
34-
'LoginMode': "Password",
35-
'Password': utils.gen_password(20),
36-
'CPU': 1,
37-
'Memory': 1024,
38-
'Disks': [{
39-
'Size': image["ImageSize"],
40-
'Type': 'LOCAL_NORMAL',
41-
'IsBoot': 'True',
42-
}],
43-
})
34+
resp = client.uhost().create_uhost_instance(
35+
{
36+
"Name": "sdk-python-example",
37+
"Zone": image["Zone"],
38+
"ImageId": image["ImageId"],
39+
"LoginMode": "Password",
40+
"Password": utils.gen_password(20),
41+
"CPU": 1,
42+
"Memory": 1024,
43+
"Disks": [
44+
{
45+
"Size": image["ImageSize"],
46+
"Type": "LOCAL_NORMAL",
47+
"IsBoot": "True",
48+
}
49+
],
50+
}
51+
)
4452
uhost_id = utils.first(resp["UHostIds"])
4553
logger.info("uhost instance is created")
4654

4755
def refresh_state():
48-
uhost = utils.first(client.uhost().describe_uhost_instance({'UHostIds': [uhost_id]}).get('UHostSet', []))
49-
if uhost.get('State') in ['Running', 'Stopped']:
50-
return uhost['State'].lower()
51-
return 'pending'
56+
uhost = utils.first(
57+
client.uhost()
58+
.describe_uhost_instance({"UHostIds": [uhost_id]})
59+
.get("UHostSet", [])
60+
)
61+
if uhost.get("State") in ["Running", "Stopped"]:
62+
return uhost["State"].lower()
63+
return "pending"
5264

5365
logger.info("wait uhost state is running ...")
5466
try:
55-
wait.wait_for_state(pending=['pending'], target=['running'], timeout=300, refresh=refresh_state)
67+
wait.wait_for_state(
68+
pending=["pending"],
69+
target=["running"],
70+
timeout=300,
71+
refresh=refresh_state,
72+
)
5673
except wait.WaitTimeoutException as e:
5774
logger.error(e)
5875
logger.info("uhost instance is running")
5976

6077
logger.info("stopping uhost for clean up resources ...")
61-
client.uhost().stop_uhost_instance({'UHostId': uhost_id})
78+
client.uhost().stop_uhost_instance({"UHostId": uhost_id})
6279

6380
try:
64-
wait.wait_for_state(pending=['pending'], target=['stopped'], timeout=180, refresh=refresh_state)
81+
wait.wait_for_state(
82+
pending=["pending"],
83+
target=["stopped"],
84+
timeout=180,
85+
refresh=refresh_state,
86+
)
6587
except wait.WaitTimeoutException as e:
6688
logger.error(e)
6789
else:
6890
logger.info("uhost instance is stopped")
6991

7092
logger.info("remove uhost instance from cloud")
71-
client.uhost().terminate_uhost_instance({'UHostId': uhost_id})
93+
client.uhost().terminate_uhost_instance({"UHostId": uhost_id})
7294

7395

74-
if __name__ == '__main__':
96+
if __name__ == "__main__":
7597
main()

0 commit comments

Comments
 (0)