summaryrefslogtreecommitdiffstats
path: root/tests/unit
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit')
-rw-r--r--tests/unit/api/conftest.py22
-rw-r--r--tests/unit/api/metric_controller_test.py37
-rw-r--r--tests/unit/api/plan_controller_test.py49
-rw-r--r--tests/unit/api/qpi_controller_test.py43
-rw-r--r--tests/unit/cli/cmd_metric_test.py14
-rw-r--r--tests/unit/cli/cmd_plan_test.py9
-rw-r--r--tests/unit/cli/cmd_qpi_test.py11
-rw-r--r--tests/unit/cli/cmd_report_test.py91
-rw-r--r--tests/unit/cli/options_test.py9
-rw-r--r--tests/unit/collector/collector_test.py (renamed from tests/unit/collector/base_test.py)0
-rw-r--r--tests/unit/loader/plan_test.py17
-rw-r--r--tests/unit/reporter/console_test.py89
-rw-r--r--tests/unit/runner/runner_test.py16
-rw-r--r--tests/unit/util/env_test.py307
-rw-r--r--tests/unit/util/logger_test.py9
15 files changed, 698 insertions, 25 deletions
diff --git a/tests/unit/api/conftest.py b/tests/unit/api/conftest.py
new file mode 100644
index 00000000..23a3be82
--- /dev/null
+++ b/tests/unit/api/conftest.py
@@ -0,0 +1,22 @@
+##############################################################################
+# Copyright (c) 2017 akhil.batra@research.iiit.ac.in and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import pytest
+
+from qtip.api import __main__
+
+
+@pytest.fixture(scope="session")
+def app():
+ return __main__.get_app().app
+
+
+@pytest.fixture(scope="session")
+def app_client(app):
+ return app.test_client()
diff --git a/tests/unit/api/metric_controller_test.py b/tests/unit/api/metric_controller_test.py
new file mode 100644
index 00000000..caba7972
--- /dev/null
+++ b/tests/unit/api/metric_controller_test.py
@@ -0,0 +1,37 @@
+##############################################################################
+# Copyright (c) 2017 akhil.batra@research.iiit.ac.in and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import httplib
+import json
+
+from qtip.base.constant import BaseProp
+
+
+def test_get_list_metrics(app_client):
+ response_success = app_client.get("/v1.0/metrics")
+ assert response_success.status_code == httplib.OK
+ metric_list = json.loads(response_success.data)['metrics']
+ assert len(metric_list) > 0
+ assert metric_list[0].endswith('.yaml')
+
+
+def test_get_metric(app_client):
+ response_success = app_client.get("/v1.0/metrics/dpi.yaml")
+ assert response_success.status_code == httplib.OK
+ metric_data = json.loads(response_success.data)
+ assert BaseProp.NAME in metric_data
+ assert BaseProp.WORKLOADS in metric_data
+ assert isinstance(metric_data[BaseProp.WORKLOADS], list)
+
+
+def test_get_metric_not_found(app_client):
+ response_not_found = app_client.get("/v1.0/metrics/fake.yaml")
+ response_data = json.loads(response_not_found.data)
+ assert response_not_found.status_code == httplib.NOT_FOUND
+ assert response_data['title'] == "Metric not found"
diff --git a/tests/unit/api/plan_controller_test.py b/tests/unit/api/plan_controller_test.py
new file mode 100644
index 00000000..136bd3c6
--- /dev/null
+++ b/tests/unit/api/plan_controller_test.py
@@ -0,0 +1,49 @@
+##############################################################################
+# Copyright (c) 2017 akhil.batra@research.iiit.ac.in and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import httplib
+import json
+
+
+from qtip.loader.plan import PlanProp
+
+
+def test_invalid_url(app_client):
+ response_url_not_found = app_client.get("/v1.0/fakeresource")
+ assert response_url_not_found.status_code == httplib.NOT_FOUND
+
+
+def test_get_list_plans(app_client):
+ response_success = app_client.get("/v1.0/plans")
+ assert response_success.status_code == httplib.OK
+ plan_list = json.loads(response_success.data)['plans']
+ assert len(plan_list) > 0
+ assert plan_list[0].endswith('.yaml')
+
+
+def test_get_plan(app_client):
+ response_success = app_client.get("/v1.0/plans/sample.yaml")
+ assert response_success.status_code == httplib.OK
+ plan_data = json.loads(response_success.data)
+ assert PlanProp.NAME in plan_data
+ assert PlanProp.DESCRIPTION in plan_data
+ assert PlanProp.CONFIG in plan_data
+ assert PlanProp.QPIS in plan_data
+
+
+def test_get_plan_not_found(app_client):
+ response_not_found = app_client.get("/v1.0/plans/fake.yaml")
+ response_data = json.loads(response_not_found.data)
+ assert response_not_found.status_code == httplib.NOT_FOUND
+ assert response_data['title'] == "Plan not found"
+
+
+def test_runner_not_implemented(app_client):
+ response_error = app_client.post("/v1.0/plans/fake.yaml?action=run", follow_redirects=False)
+ assert response_error.status_code == httplib.NOT_IMPLEMENTED
diff --git a/tests/unit/api/qpi_controller_test.py b/tests/unit/api/qpi_controller_test.py
new file mode 100644
index 00000000..6291dd9b
--- /dev/null
+++ b/tests/unit/api/qpi_controller_test.py
@@ -0,0 +1,43 @@
+##############################################################################
+# Copyright (c) 2017 akhil.batra@research.iiit.ac.in and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import httplib
+import json
+
+from qtip.base.constant import FormulaName
+from qtip.base.constant import SpecProp
+
+
+def test_get_list_qpis(app_client):
+ response_success = app_client.get("/v1.0/qpis")
+ assert response_success.status_code == httplib.OK
+ qpi_spec_list = json.loads(response_success.data)['qpis']
+ assert len(qpi_spec_list) > 0
+ assert qpi_spec_list[0].endswith('.yaml')
+
+
+def test_get_qpi(app_client):
+ response_success = app_client.get("/v1.0/qpis/compute.yaml")
+ assert response_success.status_code == httplib.OK
+ qpi_data = json.loads(response_success.data)
+ assert SpecProp.DESCRIPTION in qpi_data
+ assert SpecProp.FORMULA in qpi_data
+ assert SpecProp.SECTIONS in qpi_data
+ assert qpi_data[SpecProp.FORMULA] in FormulaName.__dict__.values()
+ sections = qpi_data[SpecProp.SECTIONS]
+ assert isinstance(sections, list)
+ for section in sections:
+ assert SpecProp.NAME in section
+
+
+def test_get_qpi_not_found(app_client):
+ response_not_found = app_client.get("/v1.0/qpis/fake.yaml")
+ response_data = json.loads(response_not_found.data)
+ assert response_not_found.status_code == httplib.NOT_FOUND
+ assert response_data['title'] == "QPI not found"
diff --git a/tests/unit/cli/cmd_metric_test.py b/tests/unit/cli/cmd_metric_test.py
index 30f3448a..cd496ad9 100644
--- a/tests/unit/cli/cmd_metric_test.py
+++ b/tests/unit/cli/cmd_metric_test.py
@@ -1,5 +1,5 @@
###############################################################
-# Copyright (c) 2016 ZTE Corp and others.
+# Copyright (c) 2017 taseer94@gmail.com and others.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
@@ -8,8 +8,8 @@
##############################################################################
import pytest
-from click.testing import CliRunner
+from click.testing import CliRunner
from qtip.cli.entry import cli
@@ -20,7 +20,9 @@ def runner():
def test_list(runner):
result = runner.invoke(cli, ['metric', 'list'])
- assert result.output == ''
+ assert 'dhrystone' and 'whetstone' and 'dpi' and \
+ 'ramspeed' and 'fake-metric' and 'ssl' \
+ in result.output
def test_run(runner):
@@ -32,8 +34,10 @@ def test_run(runner):
def test_show(runner):
- result = runner.invoke(cli, ['metric', 'show', 'fake-metric'])
- assert result.output == ''
+ result = runner.invoke(cli, ['metric', 'show', 'dhrystone'])
+ assert 'Name: dhrystone' in result.output
+ assert 'Description: A synthetic computing benchmark program intended to be representative of' \
+ 'system (integer) programming.'
result = runner.invoke(cli, ['metric', 'show'])
assert 'Missing argument "name".' in result.output
diff --git a/tests/unit/cli/cmd_plan_test.py b/tests/unit/cli/cmd_plan_test.py
index 1708c340..30025ae0 100644
--- a/tests/unit/cli/cmd_plan_test.py
+++ b/tests/unit/cli/cmd_plan_test.py
@@ -1,5 +1,5 @@
###############################################################
-# Copyright (c) 2016 ZTE Corp and others.
+# Copyright (c) 2017 taseer94@gmail.com and others.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
@@ -20,7 +20,7 @@ def runner():
def test_list(runner):
result = runner.invoke(cli, ['plan', 'list'])
- assert result.output == ''
+ assert 'Plan' and 'compute' and 'sample' in result.output
def test_run(runner):
@@ -32,8 +32,9 @@ def test_run(runner):
def test_show(runner):
- result = runner.invoke(cli, ['plan', 'show', 'fake-plan'])
- assert result.output == ''
+ result = runner.invoke(cli, ['plan', 'show', 'compute'])
+ assert 'Name: compute QPI' in result.output
+ assert 'Description: compute QPI profile'
result = runner.invoke(cli, ['plan', 'show'])
assert 'Missing argument "name".' in result.output
diff --git a/tests/unit/cli/cmd_qpi_test.py b/tests/unit/cli/cmd_qpi_test.py
index 485d5462..3d2c2613 100644
--- a/tests/unit/cli/cmd_qpi_test.py
+++ b/tests/unit/cli/cmd_qpi_test.py
@@ -1,5 +1,5 @@
###############################################################
-# Copyright (c) 2016 ZTE Corp and others.
+# Copyright (c) 2017 taseer94@gmail.com and others.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
@@ -8,9 +8,9 @@
##############################################################################
import pytest
-from click.testing import CliRunner
from qtip.cli.entry import cli
+from click.testing import CliRunner
@pytest.fixture(scope="module")
@@ -20,7 +20,7 @@ def runner():
def test_list(runner):
result = runner.invoke(cli, ['qpi', 'list'])
- assert result.output == ''
+ assert 'QPIs' and 'compute' in result.output
def test_run(runner):
@@ -32,8 +32,9 @@ def test_run(runner):
def test_show(runner):
- result = runner.invoke(cli, ['qpi', 'show', 'fake-qpi'])
- assert result.output == ''
+ result = runner.invoke(cli, ['qpi', 'show', 'compute'])
+ assert 'Name: compute' in result.output
+ assert 'Description: sample performance index of computing' in result.output
result = runner.invoke(cli, ['qpi', 'show'])
assert 'Missing argument "name".' in result.output
diff --git a/tests/unit/cli/cmd_report_test.py b/tests/unit/cli/cmd_report_test.py
new file mode 100644
index 00000000..963ce987
--- /dev/null
+++ b/tests/unit/cli/cmd_report_test.py
@@ -0,0 +1,91 @@
+###############################################################
+# Copyright (c) 2017 taseer94@gmail.com and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import pytest
+
+from click.testing import CliRunner
+from qtip.cli.entry import cli
+
+
+@pytest.fixture(scope="module")
+def runner():
+ return CliRunner()
+
+
+def test_dhrystone(runner):
+ """Test dhrystone report"""
+
+ result = runner.invoke(cli, ['report', 'show', 'dhrystone'])
+ assert "Benchmark: dhrystone" in result.output
+ assert "CPU Usage: 3%" in result.output
+ assert "Number: 40" in result.output
+ assert "Score: 63529.6" in result.output
+ assert "Single CPU:" in result.output
+ assert "Total CPUs: 40" in result.output
+
+
+def test_whetstone(runner):
+ """ Test whetstone output"""
+
+ result = runner.invoke(cli, ['report', 'show', 'whetstone'])
+ assert "Benchmark: whetstone" in result.output
+ assert "CPU Usage: 3%" in result.output
+ assert "Results:" in result.output
+ assert "Multi CPU:" in result.output
+ assert "Number: 40" in result.output
+ assert "Score: 21198.3" in result.output
+ assert "Single CPU:" in result.output
+
+
+def test_dpi(runner):
+ """ Test dpi report"""
+ result = runner.invoke(cli, ['report', 'show', 'dpi'])
+ assert "Benchmark: dpi" in result.output
+ assert "CPU Usage: 3%" in result.output
+ assert "Bits per Second: 3.638" in result.output
+ assert "Packets per Second: 1.45" in result.output
+ assert "Bits per Second: 3.69" in result.output
+ assert "Packets per Second: 1.458" in result.output
+
+
+def test_ramspeed(runner):
+ """ Test ramspeed report """
+ result = runner.invoke(cli, ['report', 'show', 'ramspeed'])
+ assert "Benchmark: ramspeed" in result.output
+ assert "CPU Usage: 3%" in result.output
+ assert "Float Addition: 10217.62" in result.output
+ assert "Float Average: 9176.88" in result.output
+ assert "Float Copy: 8127.13" in result.output
+ assert "Float Scale: 8085.40" in result.output
+ assert "Float Triad: 10277.38" in result.output
+ assert "Integer Addition: 11471.63" in result.output
+ assert "Integer Average: 11396.35" in result.output
+
+
+def test_ssl(runner):
+ """ Test ssl report"""
+
+ result = runner.invoke(cli, ['report', 'show', 'ssl'])
+ assert "Benchmark: ssl" in result.output
+ assert "CPU Usage: 3%" in result.output
+ assert "AES 128 CBC (bytes):" in result.output
+ assert "256: 584951.30k" in result.output
+ assert "RSA SIGN:" in result.output
+ assert "2048: 9.9" in result.output
+ assert "RSA VERIFY:" in result.output
+ assert "4096: 7688.5" in result.output
+
+
+def test_sys(runner):
+ """ Test sys_info """
+
+ result = runner.invoke(cli, ['report', 'show', 'ssl'])
+ assert "System Information:" in result.output
+ assert "Host Name: node-38.zte.com.cn" in result.output
+ assert "Memory: 4403.7/128524.1MB" in result.output
diff --git a/tests/unit/cli/options_test.py b/tests/unit/cli/options_test.py
index f9472814..9dbbe6f3 100644
--- a/tests/unit/cli/options_test.py
+++ b/tests/unit/cli/options_test.py
@@ -1,5 +1,5 @@
###############################################################
-# Copyright (c) 2016 ZTE Corp and others.
+# Copyright (c) 2017 taseer94@gmail.com and others.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
@@ -8,8 +8,9 @@
##############################################################################
import pytest
-from click.testing import CliRunner
+import sys
+from click.testing import CliRunner
from qtip.cli.entry import cli
@@ -28,5 +29,5 @@ class TestClass(object):
assert 'dev' in result.output
def test_debug(self, runner):
- result = runner.invoke(cli, ['-d'])
- assert '' in result.output
+ runner.invoke(cli, ['-d'])
+ assert sys.tracebacklimit == 8
diff --git a/tests/unit/collector/base_test.py b/tests/unit/collector/collector_test.py
index 17fe1af1..17fe1af1 100644
--- a/tests/unit/collector/base_test.py
+++ b/tests/unit/collector/collector_test.py
diff --git a/tests/unit/loader/plan_test.py b/tests/unit/loader/plan_test.py
index 70ae2ad5..4c92e8d5 100644
--- a/tests/unit/loader/plan_test.py
+++ b/tests/unit/loader/plan_test.py
@@ -13,15 +13,18 @@ from qtip.collector.logfile import LogfileCollector
from qtip.loader.plan import load_collector
from qtip.loader.plan import Plan
from qtip.loader.plan import PlanProp
-from qtip.loader.plan import QPISpec
-def test_init(plan):
- assert plan.name == 'doctor performance profiling'
- assert isinstance(plan.content, dict)
- for qpi in plan.qpis:
- assert isinstance(qpi, QPISpec)
+def test_construct(benchmarks_root):
+ sample = Plan('sample.yaml')
+ assert isinstance(sample, Plan)
+ # fixture can not be used in pytest.mark.parametrized
+ sample = Plan('sample.yaml', [benchmarks_root])
+ assert isinstance(sample, Plan)
+
+
+def test_invalid_construct():
with pytest.raises(TypeError) as excinfo:
Plan()
assert '__init__() takes at least 2 arguments (1 given)' \
@@ -30,7 +33,7 @@ def test_init(plan):
def test_list_all(benchmarks_root):
plan_list = list(Plan.list_all(paths=[benchmarks_root]))
- assert len(plan_list) is 2
+ assert len(plan_list) is 3
for desc in plan_list:
assert PlanProp.NAME in desc
assert PlanProp.ABSPATH in desc
diff --git a/tests/unit/reporter/console_test.py b/tests/unit/reporter/console_test.py
new file mode 100644
index 00000000..aa7f848b
--- /dev/null
+++ b/tests/unit/reporter/console_test.py
@@ -0,0 +1,89 @@
+##############################################################################
+# Copyright (c) 2017 ZTE Corporation and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import pytest
+
+from qtip.reporter.console import ConsoleReporter
+
+
+@pytest.fixture
+def console_reporter():
+ return ConsoleReporter({})
+
+
+def test_constructor(console_reporter):
+ assert isinstance(console_reporter, ConsoleReporter)
+
+
+def test_dhrystone(console_reporter):
+ """ Test dhrystone report"""
+
+ result = console_reporter.render('dhrystone')
+ assert "Benchmark: dhrystone" in result
+ assert "Number: 40" in result
+ assert "Score: 63529.6" in result
+ assert "Single CPU:" in result
+ assert "Total CPUs: 40" in result
+
+
+def test_whetstone(console_reporter):
+ """ Test whetstone output"""
+
+ result = console_reporter.render('whetstone')
+ assert "Benchmark: whetstone" in result
+ assert "Results:" in result
+ assert "Multi CPU:" in result
+ assert "Number: 40" in result
+ assert "Score: 21198.3" in result
+ assert "Single CPU:" in result
+
+
+def test_dpi(console_reporter):
+ """ Test dpi report"""
+
+ result = console_reporter.render('dpi')
+ assert "Benchmark: dpi" in result
+ assert "Bits per Second: 3.638" in result
+ assert "Packets per Second: 1.45" in result
+ assert "Bits per Second: 3.69" in result
+ assert "Packets per Second: 1.458" in result
+
+
+def test_ramspeed(console_reporter):
+ """ Test ramspeed report """
+
+ result = console_reporter.render('ramspeed')
+ assert "Float Addition: 10217.62" in result
+ assert "Float Average: 9176.88" in result
+ assert "Float Copy: 8127.13" in result
+ assert "Float Scale: 8085.40" in result
+ assert "Float Triad: 10277.38" in result
+ assert "Integer Addition: 11471.63" in result
+ assert "Integer Average: 11396.35" in result
+
+
+def test_ssl(console_reporter):
+ """ Test ssl report"""
+
+ result = console_reporter.render('ssl')
+ assert "AES 128 CBC (bytes):" in result
+ assert "256: 584951.30k" in result
+ assert "RSA SIGN:" in result
+ assert "2048: 9.9" in result
+ assert "RSA VERIFY:" in result
+ assert "4096: 7688.5" in result
+
+
+def test_sys(console_reporter):
+ """ Test sys_info """
+
+ result = console_reporter.render('ssl')
+ assert "System Information:" in result
+ assert "Host Name: node-38.zte.com.cn" in result
+ assert "Memory: 4403.7/128524.1MB" in result
diff --git a/tests/unit/runner/runner_test.py b/tests/unit/runner/runner_test.py
new file mode 100644
index 00000000..b7da1611
--- /dev/null
+++ b/tests/unit/runner/runner_test.py
@@ -0,0 +1,16 @@
+##############################################################################
+# Copyright (c) 2016 ZTE Corp and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+from qtip.runner.base import BaseRunner
+
+
+def test_constructor():
+ runner = BaseRunner()
+ assert isinstance(runner, BaseRunner)
diff --git a/tests/unit/util/env_test.py b/tests/unit/util/env_test.py
new file mode 100644
index 00000000..793d1e4e
--- /dev/null
+++ b/tests/unit/util/env_test.py
@@ -0,0 +1,307 @@
+###############################################################
+# Copyright (c) 2017 ZTE Corporation
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import time
+
+import pytest
+import mock
+from collections import defaultdict
+import socket
+
+from qtip.util import env
+from qtip.util.env import AnsibleEnvSetup
+
+
+@pytest.fixture(scope='session')
+def ansible_envsetup():
+ return AnsibleEnvSetup()
+
+
+@pytest.fixture()
+def hostfile(tmpdir):
+ fake_hostfile = tmpdir.join('hosts')
+ fake_hostfile.write("[hosts]\n")
+ fake_hostfile.write("10.20.0.3")
+ return fake_hostfile
+
+
+@pytest.fixture()
+def private_key(tmpdir):
+ fake_private_key = tmpdir.join('QtipKey')
+ fake_private_key.write("fake keypair")
+ return fake_private_key
+
+
+@pytest.fixture()
+def public_key(tmpdir):
+ fake_public_key = tmpdir.join('QtipKey.pub')
+ fake_public_key.write("fake public key")
+ return fake_public_key
+
+
+def test_all_files_exist(tmpdir):
+ exist_file = tmpdir.mkdir('qtip').join('hello.txt')
+ exist_file.write("hello")
+ non_exist_file = tmpdir.strpath + '/tmp.txt'
+ assert env.all_files_exist() is False
+ assert env.all_files_exist(str(exist_file))
+ assert env.all_files_exist(non_exist_file) is False
+ assert env.all_files_exist(str(exist_file), non_exist_file) is False
+
+
+def test_clean_file(tmpdir):
+ exist_file = tmpdir.mkdir('qtip').join('hello.txt')
+ exist_file.write("hello")
+ non_exist_file = tmpdir.strpath + '/tmp.txt'
+
+ assert env.clean_file() is False
+ assert env.clean_file(str(exist_file))
+ assert env.clean_file(non_exist_file)
+
+
+def test_init(ansible_envsetup):
+ assert 'AnsibleEnvSetup' in str(type(ansible_envsetup))
+ assert ansible_envsetup.keypair == defaultdict(str)
+ assert ansible_envsetup.hostfile is None
+ assert ansible_envsetup.host_ip_list == []
+
+
+def test_setup_exception(mocker, ansible_envsetup, hostfile):
+ with mock.patch.object(AnsibleEnvSetup, 'check_hostfile', side_effect=RuntimeError()):
+ mock_os = mocker.patch('sys.exit')
+ ansible_envsetup.setup({'hostfile': str(hostfile)})
+ assert mock_os.call_count == 1
+
+
+# TODO(zhihui_wu) Need find a smart way to write this pytest
+def test_setup(mocker, ansible_envsetup):
+ mock_check_hostfile = \
+ mocker.patch.object(AnsibleEnvSetup, 'check_hostfile')
+ mock_generate_default_hostfile = \
+ mocker.patch.object(AnsibleEnvSetup, 'generate_default_hostfile')
+ mock_fetch_ip = \
+ mocker.patch.object(AnsibleEnvSetup, 'fetch_host_ip_from_hostfile')
+ mock_check_keypair = \
+ mocker.patch.object(AnsibleEnvSetup, 'check_keypair')
+ mock_generate_default_keypair = \
+ mocker.patch.object(AnsibleEnvSetup, 'generate_default_keypair')
+ mock_pass_keypair = \
+ mocker.patch.object(AnsibleEnvSetup, 'pass_keypair_to_remote')
+ mock_check_ssh = \
+ mocker.patch.object(AnsibleEnvSetup, 'check_hosts_ssh_connectivity')
+
+ ansible_envsetup.setup({'keypair': str(private_key),
+ 'hostfile': str(hostfile)})
+ mock_check_hostfile.assert_called_with(str(hostfile))
+ mock_fetch_ip.assert_called_with()
+ mock_check_keypair.assert_called_with(str(private_key))
+ mock_pass_keypair.assert_called_with()
+ mock_check_ssh.assert_called_with()
+
+ ansible_envsetup.setup({'keypair': str(private_key)})
+ mock_generate_default_hostfile.assert_called_with()
+ mock_fetch_ip.assert_called_with()
+ mock_check_keypair.assert_called_with(str(private_key))
+ mock_pass_keypair.assert_called_with()
+ mock_check_ssh.assert_called_with()
+
+ ansible_envsetup.setup({'hostfile': str(hostfile)})
+ mock_check_hostfile.assert_called_with(str(hostfile))
+ mock_fetch_ip.assert_called_with()
+ mock_generate_default_keypair.assert_called_with()
+ mock_pass_keypair.assert_called_with()
+ mock_check_ssh.assert_called_with()
+
+ ansible_envsetup.setup()
+ mock_generate_default_hostfile.assert_called_with()
+ mock_fetch_ip.assert_called_with()
+ mock_generate_default_keypair.assert_called_with()
+ mock_pass_keypair.assert_called_with()
+ mock_check_ssh.assert_called_with()
+
+
+def test_check_keypair(mocker, ansible_envsetup, private_key, public_key):
+ with mocker.patch.object(env, 'all_files_exist', return_value=True):
+ ansible_envsetup.check_keypair(str(private_key))
+ assert ansible_envsetup.keypair['private'] == str(private_key)
+ assert ansible_envsetup.keypair['public'] == str(public_key)
+
+
+def test_check_keypair_failed(mocker, ansible_envsetup):
+ mocker.patch.object(env, 'all_files_exist', return_value=False)
+ with pytest.raises(RuntimeError) as excinfo:
+ ansible_envsetup.check_keypair(str(private_key))
+ assert 'The keypairs you in the configuration file ' \
+ 'is invalid or not existed.' == str(excinfo.value)
+ assert ansible_envsetup.keypair['private'] == ''
+ assert ansible_envsetup.keypair['public'] == ''
+
+
+@pytest.mark.parametrize("file_existence, expected", [
+ (True, 0),
+ (False, 1)
+])
+def test_generate_default_keypair(mocker, ansible_envsetup, file_existence, expected):
+ mock_os = mocker.patch('os.system')
+ mocker.patch.object(env, 'all_files_exist', return_value=file_existence)
+ ansible_envsetup.generate_default_keypair()
+ assert mock_os.call_count == expected
+ assert ansible_envsetup.keypair['private'] == env.PRIVATE_KEY
+ assert ansible_envsetup.keypair['public'] == env.PUBLIC_KEY
+
+
+@pytest.mark.parametrize("ips, expected", [
+ (['10.20.0.3'], 1),
+ (['10.20.0.3', '10.20.0.4'], 2)
+])
+def test_pass_keypair_to_remote_successful(mocker, ansible_envsetup, ips, expected):
+ ansible_envsetup.host_ip_list = ips
+ mock_pass_keypair = \
+ mocker.patch.object(AnsibleEnvSetup, '_pass_keypair', return_value=True)
+ ansible_envsetup.pass_keypair_to_remote()
+ assert mock_pass_keypair.call_count == expected
+
+
+def test_pass_keypair_to_remote_failed(mocker, ansible_envsetup):
+ ansible_envsetup.host_ip_list = ['10.20.0.3']
+ mocker.patch.object(AnsibleEnvSetup, '_pass_keypair', return_value=False)
+ with pytest.raises(RuntimeError) as excinfo:
+ ansible_envsetup.pass_keypair_to_remote()
+ assert "Failed on passing keypair to remote." in str(excinfo.value)
+
+
+def test_pass_keypair(monkeypatch, mocker, ansible_envsetup):
+ monkeypatch.setattr(time, 'sleep', lambda s: None)
+ mock_os = mocker.patch('os.system')
+ ansible_envsetup._pass_keypair('10.20.0.3', str(private_key))
+ assert mock_os.call_count == 2
+
+
+def test_pass_keypair_exception(ansible_envsetup):
+ with mock.patch('os.system', side_effect=Exception()) as mock_os:
+ result = ansible_envsetup._pass_keypair('10.20.0.3', str(private_key))
+ assert result is False
+ assert mock_os.call_count == 1
+
+
+def test_check_hostfile(mocker, ansible_envsetup, hostfile):
+ ansible_envsetup.check_hostfile(str(hostfile))
+ assert ansible_envsetup.hostfile == str(hostfile)
+
+ with pytest.raises(RuntimeError) as excinfo:
+ mocker.patch.object(env, 'all_files_exist', return_value=False)
+ ansible_envsetup.check_hostfile(str(hostfile))
+ assert str(excinfo.value) == 'The hostfile {0} is invalid or not ' \
+ 'existed.'.format(str(hostfile))
+
+
+def test_default_hostfile_non_existed(mocker, ansible_envsetup):
+ with mocker.patch.object(env, 'all_files_exist', return_value=False):
+ mock_generate_hostfile_via_installer = \
+ mocker.patch.object(AnsibleEnvSetup,
+ '_generate_hostfile_via_installer')
+ ansible_envsetup.generate_default_hostfile()
+ mock_generate_hostfile_via_installer.assert_called_once_with()
+
+
+def test_default_hostfile_existed(mocker, ansible_envsetup):
+ with mocker.patch.object(env, 'all_files_exist', return_value=True):
+ mock_generate_hostfile_via_installer = \
+ mocker.patch.object(AnsibleEnvSetup,
+ '_generate_hostfile_via_installer')
+ ansible_envsetup.generate_default_hostfile()
+ mock_generate_hostfile_via_installer.assert_not_called()
+
+
+@pytest.mark.parametrize("test_input, expected", [
+ (({}, KeyError), 'INSTALLER_TYPE'),
+ (({'INSTALLER_TYPE': 'fuel'}, KeyError), 'INSTALLER_IP'),
+ (({'INSTALLER_TYPE': 'fuel_1', 'INSTALLER_IP': '10.20.0.2'}, ValueError),
+ 'fuel_1 is not supported'),
+ (({'INSTALLER_TYPE': 'fuel', 'INSTALLER_IP': ''}, ValueError),
+ 'The value of environment variable INSTALLER_IP is empty')
+])
+def test_generate_hostfile_via_installer_exception(monkeypatch, ansible_envsetup, test_input, expected):
+ if test_input[0]:
+ for key in test_input[0]:
+ monkeypatch.setenv(key, test_input[0][key])
+
+ with pytest.raises(test_input[1]) as excinfo:
+ ansible_envsetup._generate_hostfile_via_installer()
+ assert expected in str(excinfo.value)
+
+
+def test_generate_hostfile_via_installer(monkeypatch, mocker, ansible_envsetup):
+ monkeypatch.setenv('INSTALLER_TYPE', 'fuel')
+ monkeypatch.setenv('INSTALLER_IP', '10.20.0.2')
+ mock_os = mocker.patch('os.system')
+ ansible_envsetup._generate_hostfile_via_installer()
+ assert mock_os.call_count == 1
+ assert ansible_envsetup.hostfile == env.HOST_FILE
+
+
+def test_fetch_host_ip_from_hostfile(ansible_envsetup, hostfile):
+ ansible_envsetup.hostfile = str(hostfile)
+ ansible_envsetup.fetch_host_ip_from_hostfile()
+ assert ansible_envsetup.host_ip_list == ['10.20.0.3']
+
+
+def test_fetch_host_ip_from_empty_hostfile(ansible_envsetup, tmpdir):
+ empty_hostfile = tmpdir.join('empty_hostfile')
+ empty_hostfile.write("")
+ ansible_envsetup.hostfile = str(empty_hostfile)
+ with pytest.raises(ValueError) as excinfo:
+ ansible_envsetup.fetch_host_ip_from_hostfile()
+ assert str(excinfo.value) == "The hostfile doesn't include host ip addresses."
+
+
+@pytest.mark.parametrize("ips, expected", [
+ (['10.20.0.3'], 1),
+ (['10.20.0.3', '10.20.0.4'], 2)
+])
+def test_check_hosts_ssh_connectivity(mocker, ansible_envsetup, ips, expected):
+ ansible_envsetup.host_ip_list = ips
+ mock_ssh_is_ok = \
+ mocker.patch.object(AnsibleEnvSetup, '_ssh_is_ok', return_value=True)
+ ansible_envsetup.check_hosts_ssh_connectivity()
+ assert mock_ssh_is_ok.call_count == expected
+
+
+def test_check_hosts_ssh_connectivity_failed(mocker, ansible_envsetup):
+ ansible_envsetup.host_ip_list = ['10.20.0.3']
+ mocker.patch.object(AnsibleEnvSetup, '_ssh_is_ok', return_value=False)
+ with pytest.raises(RuntimeError) as excinfo:
+ ansible_envsetup.check_hosts_ssh_connectivity()
+ assert "Failed on checking hosts ssh connectivity." == str(excinfo.value)
+
+
+@pytest.mark.parametrize("stderrinfo, expected", [
+ ('', True),
+ ('sorry', False)
+])
+def test_ssh_is_ok(mocker, ansible_envsetup, private_key, stderrinfo, expected):
+ stderr = mock.MagicMock()
+ stderr.readlines.return_value = stderrinfo
+ mock_sshclient = mocker.patch('paramiko.SSHClient')
+ test_ssh_client = mock_sshclient.return_value
+ test_ssh_client.exec_command.return_value = ('', '', stderr)
+ result = ansible_envsetup._ssh_is_ok('10.20.0.3', str(private_key))
+ assert result == expected
+ test_ssh_client.connect.assert_called_once_with(
+ '10.20.0.3', key_filename=str(private_key))
+ test_ssh_client.exec_command.assert_called_with('uname')
+
+
+def test_ssh_exception(monkeypatch, mocker, ansible_envsetup):
+ monkeypatch.setattr(time, 'sleep', lambda s: None)
+ mock_sshclient = mocker.patch('paramiko.SSHClient')
+ test_ssh_client = mock_sshclient.return_value
+ test_ssh_client.exec_command.side_effect = socket.error()
+ result = ansible_envsetup._ssh_is_ok('10.20.0.3', str(private_key), attempts=1)
+ assert result is False
diff --git a/tests/unit/util/logger_test.py b/tests/unit/util/logger_test.py
index 339b2bf6..78c4c109 100644
--- a/tests/unit/util/logger_test.py
+++ b/tests/unit/util/logger_test.py
@@ -1,3 +1,12 @@
+##############################################################################
+# Copyright (c) 2017 ZTE Corporation and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
import pytest
from qtip.util import logger