Skip to content

Commit 05b2c3c

Browse files
Ahmed El-Sayedgrimpy
Ahmed El-Sayed
authored andcommitted
add tests (#1590)
* add tests
1 parent a26ce1c commit 05b2c3c

File tree

227 files changed

+20795
-142
lines changed

Some content is hidden

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

227 files changed

+20795
-142
lines changed

tests/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## OpenvCloud Functional Tests
2+
3+
Please only put **internal** documentation on this page.
4+
5+
There are two types of functional tests, for each of them there is a subdirectory:
6+
7+
- [Tests designed to run on a physical compute node](./docs/compute_node_hosted/compute_node_hosted.md)
8+
9+
10+
- [Tests designed to run on ovc_master](./docs/ovc_master_hosted/ovc_master_hosted.md)

tests/RESTful/README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
## OpenvCloud RESTful api Tests
2+
3+
4+
5+
### Continues Integration
6+
7+
### Travis
8+
You can trigger the build from [Travis website](https://travis-ci.org/0-complexity/G8_testing) or [CI-Dashboard](https://travis-dash.gig.tech/).
9+
10+
#### Prerequisites
11+
Travis CI build uses the environment's controller to execute the tests from it, so if your environment controller doesn't have public ip you have to:
12+
- Install zerotier [ZeroTier](zerotier.com/network) on the controller.
13+
- Create zerotier network and make the controller join it.
14+
15+
#### Travis Parameters
16+
- ```ctrl_ipaddress```: controller's ip address (zerotier ip in case your using zerotier).
17+
- ```ctrl_user```: controller's non-root user (default: gig)
18+
- ```ctrl_user_password```: controller user ssh password.
19+
- ```environment```: environment's location code.
20+
- ```restful_ip```: the ip of the api server
21+
- ```restful_port```: the port of the api server
22+
- ```username```: [itsyou.online](https://itsyou.online) username
23+
- ```client_id```: [itsyou.online](https://itsyou.online) client id
24+
- ```client_secret```: [itsyou.online](https://itsyou.online) client secret
25+
26+
- ```jobs```: jobs to be executed (for example ```ovc-restful``` to execute only ovc and restful jobs).
27+
- ```restful_testsuite_dir```: restful tests path.
28+
29+
- ##### In case you are using zerotier
30+
- ```zerotier_network```: zerotier network id.
31+
- ```zerotier_token```: zerotier account token.
32+
33+
### LOCAL EXECUTION:
34+
As long as your machine can ping the enviroment, You can execute this test suite from your local mcahine. You only need to update the `config.ini` file to be look like that
35+
```
36+
[main]
37+
ip=be-g8-3.demo.greenitglobe.com
38+
port=443
39+
username=gig_qa_1@itsyouonline
40+
client_id=********************************
41+
client_secret=****************************
42+
location=be-g8-3
43+
```
44+
then you can fire it using nosetests.
45+
46+
#### Example
47+
```bash
48+
nosetests-3.4 -sv --logging-level=WARNING --rednose testcases/cloudapi/test01_disks.py --tc-file config.ini
49+
```
50+
51+
#### Steps to add new test case:
52+
To implement any test case in REST APIs test suite please, create a new task with the following pattern:
53+
54+
````yaml
55+
TC name:
56+
TC ID:
57+
API:
58+
59+
SCENARIOS:
60+
1- PERMISSION scenario.
61+
Parameterize [permitted user do correct actions > success,
62+
permitted user do incorrect actions > fail,
63+
non-permitted user do actions > fail]
64+
2- OPERATION scenarioS:
65+
You can create any number of test cases to be sure that it will cover almost all use cases of this API.
66+
67+
NOSETEST COMMAND:
68+
nosetest command to fire these test cases.
69+
```
70+

tests/RESTful/config.ini

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[main]
2+
ip=
3+
port=
4+
username=
5+
client_id=
6+
client_secret=

tests/RESTful/framework/__init__.py

Whitespace-only changes.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from testconfig import config
2+
from framework.utils.ovc_client import Client
3+
from framework.utils.utils import Utils
4+
5+
ip = config['main']['ip']
6+
port = int(config['main']['port'])
7+
client_id = config['main']['client_id']
8+
client_secret = config['main']['client_secret']
9+
10+
api_client = Client(ip, port, client_id, client_secret)
11+
api_client.load_swagger()
12+
13+
utils = Utils()

tests/RESTful/framework/api/client.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
from framework.api.cloudapi.cloudapi import Cloudapi
2+
from framework.api.system.system import System
3+
from framework.api.libcloud.libcloud import Libcloud
4+
from framework.api.cloudbroker.cloudbroker import Cloudbroker
5+
from testconfig import config
6+
import time
7+
from framework.utils.ovc_client import Client as api_client
8+
import random
9+
10+
11+
12+
class Client:
13+
def __init__(self, client_id=None, client_secret=None):
14+
15+
ip = config['main']['ip']
16+
port = int(config['main']['port'])
17+
self.api_client = api_client(ip, port, client_id, client_secret)
18+
if client_id:
19+
self.api_client.load_swagger()
20+
self.cloudapi = Cloudapi(self.api_client)
21+
self.cloudbroker = Cloudbroker(self.api_client)
22+
self.libcloud = Libcloud(self.api_client)
23+
self.system = System(self.api_client)
24+
self._whoami = config['main']['username']
25+
26+
27+
def set_auth_header(self, value):
28+
self.api_client._session.headers['Authorization'] = value
29+
30+
def create_user(self, **kwargs):
31+
data, response = self.cloudbroker.user.create(**kwargs)
32+
33+
if response.status_code != 200:
34+
return False
35+
36+
return data['username'], data['password']
37+
38+
def create_account(self, **kwargs):
39+
data, response = self.cloudbroker.account.create(username=self._whoami, ** kwargs)
40+
41+
if response.status_code != 200:
42+
return False
43+
44+
account_id = int(response.text)
45+
return account_id
46+
47+
def create_cloudspace(self, accountId, location, **kwargs):
48+
data, response = self.cloudapi.cloudspaces.create(accountId=accountId, location=location, access=self._whoami, **kwargs)
49+
50+
if response.status_code != 200:
51+
return False
52+
53+
cloudspace_id = int(response.text)
54+
55+
for _ in range(20):
56+
response = self.cloudapi.cloudspaces.get(cloudspaceId=cloudspace_id)
57+
if response.json()['status'] == 'DEPLOYED':
58+
break
59+
time.sleep(5)
60+
else:
61+
return False
62+
63+
return cloudspace_id
64+
65+
def get_environment(self):
66+
env_location = config['main']['location']
67+
locations = (self.api_client.cloudapi.locations.list()).json()
68+
for location in locations:
69+
if env_location == location['locationCode']:
70+
return location
71+
else:
72+
raise Exception("can't find the %s environment location in grid" % env_location)
73+
74+
def get_random_locations(self):
75+
return random.choice(self.cloudapi.locations.list())['locationCode']
76+
77+
def wait_for_cloudspace_status(self,cloudspaceId,status= "DEPLOYED", timeout=300):
78+
response = self.cloudapi.cloudspaces.get(cloudspaceId=cloudspaceId)
79+
cs_status=response.json()["status"]
80+
for _ in range(timeout):
81+
if cs_status == status:
82+
break
83+
time.sleep(1)
84+
response = self.api_client.cloudapi.cloudspaces.get(cloudspaceId=cloudspaceId)
85+
cs_status=response.json()["status"]
86+
87+
return cs_status
88+
89+
def authenticate_user(self, username=None, password=None, **kwargs):
90+
if not username or password:
91+
username, password = self.create_user(**kwargs)
92+
93+
api = Client()
94+
response = api.system.usermanager.authenticate(name=username, secret=password)
95+
response.raise_for_status
96+
return api, username
97+
98+
99+
def get_running_nodeId(self, except_nodeid=None):
100+
nodes = self.api_client.cloudbroker.computenode.list().json()
101+
for node in nodes:
102+
if int(node['referenceId']) != except_nodeid and node['status'] == 'ENABLED':
103+
return int(node['referenceId'])
104+
else:
105+
return None

tests/RESTful/framework/api/cloudapi/__init__.py

Whitespace-only changes.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
from framework.api import utils
2+
import random
3+
4+
class Accounts:
5+
def __init__(self, api_client):
6+
self._api = api_client
7+
8+
def list(self):
9+
return self._api.cloudapi.accounts.list()
10+
11+
def get(self, accountId):
12+
return self._api.cloudapi.accounts.get(accountId=accountId)
13+
14+
def create(self, access, **kwargs):
15+
data = {
16+
'name': utils.random_string(),
17+
'access': access,
18+
'maxMemoryCapacity': -1,
19+
'maxVDiskCapacity': -1,
20+
'maxCPUCapacity': -1,
21+
'maxNetworkPeerTransfer': -1,
22+
'maxNumPublicIP': -1,
23+
}
24+
data.update(** kwargs)
25+
return data, self._api.cloudapi.accounts.create(** data)
26+
27+
def update(self, accountId, **kwargs):
28+
return self._api.cloudapi.accounts.update(accountId=accountId, **kwargs)
29+
30+
def addUser(self, accountId, userId, accesstype='ARCXDU'):
31+
return self._api.cloudapi.accounts.addUser(
32+
accountId=accountId,
33+
userId=userId,
34+
accesstype=accesstype
35+
)
36+
37+
def deleteUser(self, accountId, userId, recursivedelete=False):
38+
return self._api.cloudapi.accounts.deleteUser(
39+
accountId=accountId,
40+
userId=userId,
41+
recursivedelete=recursivedelete
42+
)
43+
44+
def updateUser(self, accountId, userId, **kwargs):
45+
data = {
46+
'accountId': accountId,
47+
'userId': userId,
48+
'accesstype':random.choice(['R', 'RCX', 'ARCXDU'])
49+
}
50+
data.update(**kwargs)
51+
return data, self._api.cloudapi.accounts.updateUser(** data)
52+
53+
def listTemplates(self, accountId):
54+
return self._api.cloudapi.accounts.listTemplates(accountId=accountId)
55+
56+
def getConsumedCloudUnits(self, accountId):
57+
return self._api.cloudapi.accounts.getConsumedCloudUnits(accountId=accountId)
58+
59+
def getConsumedCloudUnitsByType(self, accountId, **kwargs):
60+
data = {
61+
'accountId':accountId,
62+
'cutype': random.choice(['CU_M', 'CU_C', 'CU_D', 'CU_S', 'CU_A', 'CU_NO', 'CU_NP', 'CU_I'])
63+
}
64+
data.update(**kwargs)
65+
return self._api.cloudapi.accounts.getConsumedCloudUnitsByType(** data)
66+
67+
def getConsumption(self, accountId, start, end):
68+
return self._api.cloudapi.accounts.getConsumption(
69+
accountId=accountId,
70+
start=start,
71+
end=end
72+
)
73+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from framework.api.cloudapi.accounts import Accounts
2+
from framework.api.cloudapi.cloudspaces import Cloudspaces
3+
from framework.api.cloudapi.disks import Disks
4+
from framework.api.cloudapi.externalnetwork import ExternalNetwork
5+
from framework.api.cloudapi.images import Images
6+
from framework.api.cloudapi.locations import Locations
7+
from framework.api.cloudapi.machines import Machines
8+
from framework.api.cloudapi.portforwarding import Portforwarding
9+
from framework.api.cloudapi.sizes import Sizes
10+
from framework.api.cloudapi.users import Users
11+
12+
class Cloudapi:
13+
def __init__(self, api_client):
14+
self.accounts = Accounts(api_client)
15+
self.cloudspaces = Cloudspaces(api_client)
16+
self.disks = Disks(api_client)
17+
self.externalnetwork = ExternalNetwork(api_client)
18+
self.images = Images(api_client)
19+
self.locations = Locations(api_client)
20+
self.machines = Machines(api_client)
21+
self.portforwarding = Portforwarding(api_client)
22+
self.sizes = Sizes(api_client)
23+
self.users = Users(api_client)

0 commit comments

Comments
 (0)