Skip to content

Commit

Permalink
Testcases to cover S3 in the smoke test and updates in accordance wit…
Browse files Browse the repository at this point in the history
…h NeoFS 0.13.0 have been updated (#5)

* Coverage of the S3 gateway and "S3-gate - NeoFS - HTTP-gate" interaction has been added to the Selectel smoke test.
  • Loading branch information
anatoly-bogatyrev authored Dec 16, 2020
1 parent a20ec58 commit bb3c2bd
Show file tree
Hide file tree
Showing 14 changed files with 259 additions and 162 deletions.
82 changes: 42 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,96 +1,98 @@
## Запуск тесткейсов
## Testcases execution

### Первичная подготовка
### Initial preparation

1. Установить neofs-cli
1. Install neofs-cli
- `git clone [email protected]:nspcc-dev/neofs-node.git`
- `cd neofs-node`
- `make`
- `sudo cp bin/neofs-cli /usr/local/bin/neofs-cli` or add alias path to bin/neofs-cli

2. Установить cdn-authmate
2. Install cdn-authmate
- `git clone [email protected]:nspcc-dev/cdn-authmate.git`
- `cd cdn-authmate`
- `make build`
- `sudo cp bin/cdn-authmate /usr/local/bin/cdn-authmate` or add alias path to bin/cdn-authmate

3. Устаносить зависимости для Testcases
3. Install Testcases dependencies
- `pip3 install robotframework`
- `pip3 install pexpect`
- `pip3 install requests`
- `pip3 install boto3`
- `pip3 install docker`

(pip3 заменить на соответсвующий менеджер пакетов python в системе).
(replace pip3 with the appropriate python package manager on the system).

При этом должен быть запущен dev-env с тестируемым окружением.
In this case, dev-env should be running with the tested environment.

### Запуск тесткейсов
### Run

1. Выполнить `make run`
1. Execute the command `make run`

2. Логи будут доступны в папке artifacts/ после завершения тестов с любым из статусов.
2. Logs will be available in the artifacts/ directory after tests with any of the statuses are completed.


### Запуск произвольного тесткейса
### Running an arbitrary test case

Для запуска произвольного тесткейса нужно выполнить команду:
To run an arbitrary testcase, you need to run the command:
`robot --timestampoutputs --outputdir artifacts/ robot/testsuites/integration/<testsuite name>.robot `

Для запуска доступны следущие сценарии:
The following scripts are available for execution:

* acl_basic.robot - базовый ACL
* acl_extended.robot - extended ACL
* acl_baearer.robot - Bearer Token ACL
* object_complex.robot - операции над простым объектом
* object_simple.robot - операции над большим объектом
* withdraw.robot - оперция Deposit и Withdraw с счета NeoFS
* netmap_simple.robot - проверка Placement policy
* replication.robot - базовый тесткейс проверки репликации объектов
* http_gate.robot - проверка HTTP-gate и интеграции с NeoFS
* s3_gate.robot - проверка S3-gate и интеграции с NeoFS
* acl_basic.robot
* acl_extended.robot
* acl_baearer.robot
* object_complex.robot
* object_simple.robot
* withdraw.robot
* netmap_simple.robot
* replication.robot
* http_gate.robot
* s3_gate.robot


## Запуск smoke-тестов
## Smoke test execution

Есть сьют со smoke-тестами для CDN-гейтов `robot/testsuites/smoke/selectelcdn_smoke.robot`.
There is a suite with smoke tests for CDN gates `robot/testsuites/smoke/selectelcdn_smoke.robot`.

По умолчанию кейворды используют переменные из файла `robot/resources/lib/neofs_int_vars.py`.
By default, keywords use variables from a file `robot/resources/lib/neofs_int_vars.py`.
```
robot --outputdir artifacts/ robot/testsuites/smoke/selectelcdn_smoke.robot
```

### Первичная подготовка
### Initial preparation

1. Ему требуются отдельные переменные, в отличие от сьютов NeoFS, которые запускаются на
девэнве. Чтобы библиотеки кейвордов их использовали, нужно установить переменную
окружения
1. It requires separate variables, unlike the NeoFS suites, which run on
dev-env. In order for the keyword libraries to use them, you need to set the environment variable
```
export ROBOT_PROFILE=selectel_smoke
```

Dev-env не нужен. Но нужно установить neo-go.
Dev-env is not needed. But you need to install neo-go.

2. Установить neo-go
2. Install neo-go
- `git clone [email protected]:nspcc-dev/neo-go.git`
- `cd neo-go`
- `make`
- `sudo cp bin/neo-go /usr/local/bin/neo-go` or add alias path to bin/neo-go

3. To run smoke test: `robot --timestampoutputs --outputdir artifacts/ robot/testsuites/smoke/selectelcdn_smoke.robot`

## Генерация документации

Для генерации документации по шагам:
## Generation of documentation

To generate Keywords documentation:
```
python3 -m robot.libdoc robot/resources/lib/neofs.py docs/NeoFS_Library.html
python3 -m robot.libdoc robot/resources/lib/payment_neogo.py docs/Payment_Library.html
```

Для генерации документации по тесткейсам:
To generate testcases documentation:
```
python3 -m robot.testdoc robot/testsuites/integration/ docs/testcases.html
```

## Создание тесткейсов
## Testcases implementation

### Source code overview

Expand All @@ -102,11 +104,11 @@ python3 -m robot.testdoc robot/testsuites/integration/ docs/testcases.html

`robot/variables/` - All variables for tests. It is possible to add the auto-loading logic of parameters from the smart-contract in the future. Contain python files.

`robot/testsuites/` - Robot Test Suites and Test Cases.
`robot/testsuites/` - Robot TestSuites and TestCases.

`robot/testsuites/integration/` - Integration test suites and test cases
`robot/testsuites/integration/` - Integration test suites and testcases

`robot/testsuites/fi/` - Fault Injection test suites and test cases
`robot/testsuites/fi/` - Fault Injection testsuites and testcases

### Code style

Expand All @@ -129,7 +131,7 @@ On keywords definition, one should specify variable type, e.g. path: str

### Robot style

Следует всегда заполнять секции [Tags] и [Documentation] для Testcase'ов и Documentation для Test Suite'ов.
You should always complete the [Tags] and [Documentation] sections for Testcases and Documentation for Test Suites.

### Robot-framework User Guide

Expand Down
1 change: 1 addition & 0 deletions keys/s3_selectel_hcs.pub.key
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
=b���|vn�b�%����a���-ie���=
2 changes: 1 addition & 1 deletion robot/resources/lib/gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def init_s3_credentials(private_key: str, s3_key):
logger.info("Cmd: %s" % Cmd)
try:
complProc = subprocess.run(Cmd, check=True, universal_newlines=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=150, shell=True)
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=360, shell=True)
output = complProc.stdout
logger.info("Output: %s" % output)

Expand Down
62 changes: 27 additions & 35 deletions robot/resources/lib/neofs.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@
from robot.api.deco import keyword
from robot.api import logger
import random
import base64
import base58
import docker

if os.getenv('ROBOT_PROFILE') == 'selectel_smoke':
from selectelcdn_smoke_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT,
NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT)
NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT, NEOFS_NETMAP)
else:
from neofs_int_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT,
NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT)
NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT, NEOFS_NETMAP)

ROBOT_AUTO_KEYWORDS = False

Expand Down Expand Up @@ -64,22 +67,13 @@ def stop_nodes(down_num: int, *nodes_list):

# select nodes to stop from list
stop_nodes = random.sample(nodes_list, down_num)

for node in stop_nodes:
m = re.search(r'(s\d+).', node)
node = m.group(1)

Cmd = f'docker stop {node}'
logger.info("Cmd: %s" % Cmd)

try:
complProc = subprocess.run(Cmd, check=True, universal_newlines=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=150, shell=True)
output = complProc.stdout
logger.info("Output: %s" % output)

except subprocess.CalledProcessError as e:
raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
client = docker.APIClient()
client.stop(node)

return stop_nodes

Expand All @@ -90,20 +84,9 @@ def start_nodes(*nodes_list):
for node in nodes_list:
m = re.search(r'(s\d+).', node)
node = m.group(1)

Cmd = f'docker start {node}'
logger.info("Cmd: %s" % Cmd)

try:
complProc = subprocess.run(Cmd, check=True, universal_newlines=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=150, shell=True)
output = complProc.stdout
logger.info("Output: %s" % output)

except subprocess.CalledProcessError as e:
raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))


client = docker.APIClient()
client.start(node)

@keyword('Get nodes with object')
def get_nodes_with_object(private_key: str, cid: str, oid: str):
storage_nodes = _get_storage_nodes(private_key)
Expand Down Expand Up @@ -205,6 +188,10 @@ def form_bearertoken_file_for_all_ops(file_name: str, private_key: str, cid: str

eacl = get_eacl(private_key, cid)
input_records = ""

cid_base58_b = base58.b58decode(cid)
cid_base64 = base64.b64encode(cid_base58_b).decode("utf-8")

if eacl:
res_json = re.split(r'[\s\n]+\][\s\n]+\}[\s\n]+Signature:', eacl)
records = re.split(r'"records": \[', res_json[0])
Expand All @@ -215,7 +202,7 @@ def form_bearertoken_file_for_all_ops(file_name: str, private_key: str, cid: str
"body": {
"eaclTable": {
"containerID": {
"value": \"""" + cid + """"
"value": \"""" + str(cid_base64) + """"
},
"records": [
{
Expand Down Expand Up @@ -317,6 +304,10 @@ def form_bearertoken_file_filter_for_all_ops(file_name: str, private_key: str, c
# SEARCH should be allowed without filters to use GET, HEAD, DELETE, and SEARCH? Need to clarify.

eacl = get_eacl(private_key, cid)

cid_base58_b = base58.b58decode(cid)
cid_base64 = base64.b64encode(cid_base58_b).decode("utf-8")

input_records = ""
if eacl:
res_json = re.split(r'[\s\n]+\][\s\n]+\}[\s\n]+Signature:', eacl)
Expand All @@ -328,7 +319,7 @@ def form_bearertoken_file_filter_for_all_ops(file_name: str, private_key: str, c
"body": {
"eaclTable": {
"containerID": {
"value": \"""" + cid + """"
"value": \"""" + str(cid_base64) + """"
},
"records": [
{
Expand Down Expand Up @@ -535,7 +526,7 @@ def create_container(private_key: str, basic_acl:str="", rule:str="REP 2 IN X CB
createContainerCmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} container create --policy "{rule}" {basic_acl} --await'
logger.info("Cmd: %s" % createContainerCmd)
complProc = subprocess.run(createContainerCmd, check=True, universal_newlines=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=150, shell=True)
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=300, shell=True)
output = complProc.stdout
logger.info("Output: %s" % output)
cid = _parse_cid(output)
Expand Down Expand Up @@ -816,9 +807,10 @@ def delete_object(private_key: str, cid: str, oid: str, bearer: str):
bearer_token = f"--bearer {bearer}"

ObjectCmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} object delete --cid {cid} --oid {oid} {bearer_token}'
logger.info("Cmd: %s" % ObjectCmd)
try:
complProc = subprocess.run(ObjectCmd, check=True, universal_newlines=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=30, shell=True)
logger.info("Output: %s" % complProc.stdout)
except subprocess.CalledProcessError as e:
raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
Expand Down Expand Up @@ -995,7 +987,7 @@ def _parse_cid(output: str):
return cid

def _get_storage_nodes(private_key: bytes):
storage_nodes = ['s01.neofs.devenv:8080', 's02.neofs.devenv:8080','s03.neofs.devenv:8080','s04.neofs.devenv:8080']
#storage_nodes = ['s01.neofs.devenv:8080', 's02.neofs.devenv:8080','s03.neofs.devenv:8080','s04.neofs.devenv:8080']
#NetmapCmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} status netmap'
#complProc = subprocess.run(NetmapCmd, check=True, universal_newlines=True,
# stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
Expand All @@ -1011,8 +1003,8 @@ def _get_storage_nodes(private_key: bytes):
# Will be fixed when netmap will be added to cli

#storage_nodes.append()
logger.info("Storage nodes: %s" % storage_nodes)
return storage_nodes
logger.info("Storage nodes: %s" % NEOFS_NETMAP)
return NEOFS_NETMAP


def _search_object(node:str, private_key: str, cid:str, oid: str):
Expand Down
2 changes: 2 additions & 0 deletions robot/resources/lib/neofs_int_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
NEOFS_NEO_API_ENDPOINT = 'http://main_chain.neofs.devenv:30333'
HTTP_GATE = 'http://http.neofs.devenv'
S3_GATE = 'https://s3.neofs.devenv:8080'
NEOFS_CONTRACT = "5f490fbd8010fd716754073ee960067d28549b7d"
NEOFS_NETMAP = ['s01.neofs.devenv:8080', 's02.neofs.devenv:8080','s03.neofs.devenv:8080','s04.neofs.devenv:8080']
13 changes: 6 additions & 7 deletions robot/resources/lib/payment_neogo.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from robot.libraries.BuiltIn import BuiltIn

ROBOT_AUTO_KEYWORDS = False
NEOFS_CONTRACT = "5f490fbd8010fd716754073ee960067d28549b7d"

if os.getenv('ROBOT_PROFILE') == 'selectel_smoke':
from selectelcdn_smoke_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT,
Expand All @@ -24,8 +25,6 @@
NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT)


NEOFS_CONTRACT = "5f490fbd8010fd716754073ee960067d28549b7d"

@keyword('Init wallet')
def init_wallet():

Expand Down Expand Up @@ -98,12 +97,12 @@ def dump_privkey(wallet: str, address: str):
return out

@keyword('Transfer Mainnet Gas')
def transfer_mainnet_gas(wallet: str, address: str, address_to: str, amount: int):
cmd = ( f"{NEOGO_CLI_PREFIX} wallet nep5 transfer -w {wallet} -r http://main_chain.neofs.devenv:30333 --from {address} "
f"--to {address_to} --token gas --amount {amount}" )
def transfer_mainnet_gas(wallet: str, address: str, address_to: str, amount: int, wallet_pass:str=''):
cmd = ( f"{NEOGO_CLI_PREFIX} wallet nep5 transfer -w {wallet} -r {NEOFS_NEO_API_ENDPOINT} --from {address} "
f"--to {address_to} --token gas --amount {amount}" )

logger.info(f"Executing command: {cmd}")
out = _run_sh_with_passwd('', cmd)
out = _run_sh_with_passwd(wallet_pass, cmd)
logger.info(f"Command completed with output: {out}")

if not re.match(r'^(\w{64})$', out):
Expand All @@ -113,7 +112,7 @@ def transfer_mainnet_gas(wallet: str, address: str, address_to: str, amount: int

@keyword('Withdraw Mainnet Gas')
def withdraw_mainnet_gas(wallet: str, address: str, scripthash: str, amount: int):
cmd = ( f"{NEOGO_CLI_PREFIX} contract invokefunction -w {wallet} -a {address} -r http://main_chain.neofs.devenv:30333 "
cmd = ( f"{NEOGO_CLI_PREFIX} contract invokefunction -w {wallet} -a {address} -r {NEOFS_NEO_API_ENDPOINT} "
f"{NEOFS_CONTRACT} withdraw {scripthash} int:{amount} -- {scripthash}" )

logger.info(f"Executing command: {cmd}")
Expand Down
4 changes: 3 additions & 1 deletion robot/resources/lib/selectelcdn_smoke_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@
# selectel main chain on lobachevsky-1
NEOFS_NEO_API_ENDPOINT = "http://92.53.71.51:20332"
HTTP_GATE = 'http://92.53.71.51:38080'
S3_GATE = 'https://92.53.71.51:28080'
S3_GATE = 'https://92.53.71.51:28080'
NEOFS_CONTRACT = "5f490fbd8010fd716754073ee960067d28549b7d"
NEOFS_NETMAP = ['92.53.71.51:18080', '92.53.71.52:18080','92.53.71.53:18080','92.53.71.54:18080', '92.53.71.55:18080']
Loading

0 comments on commit bb3c2bd

Please sign in to comment.