Change in vdsm[ovirt-3.5]: ssl: ssl socket may throw sslerror during reading
by Piotr Kliczewski
Piotr Kliczewski has uploaded a new change for review.
Change subject: ssl: ssl socket may throw sslerror during reading
......................................................................
ssl: ssl socket may throw sslerror during reading
When client closes socket in not clean way sometimes we can get SSLError
with unexpected eof. When this situation occurs we need to make sure to
handle this situation properly.
Bug-Url: https://bugzilla.redhat.com/1265965
Change-Id: I8de60d91f81b08e9cb78df07f09d2bcc903c1bad
Signed-off-by: pkliczewski <piotr.kliczewski(a)gmail.com>
---
M lib/yajsonrpc/betterAsyncore.py
1 file changed, 3 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/59/46659/1
diff --git a/lib/yajsonrpc/betterAsyncore.py b/lib/yajsonrpc/betterAsyncore.py
index 70bfb7e..f4fe768 100644
--- a/lib/yajsonrpc/betterAsyncore.py
+++ b/lib/yajsonrpc/betterAsyncore.py
@@ -24,6 +24,7 @@
from threading import Lock
from collections import deque
+from M2Crypto import SSL
# This is a copy of the standard library asyncore converted to support
@@ -299,6 +300,8 @@
return ''
else:
raise
+ except SSL.SSLError:
+ self.handle_close()
def send(self, data):
try:
--
To view, visit https://gerrit.ovirt.org/46659
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8de60d91f81b08e9cb78df07f09d2bcc903c1bad
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Piotr Kliczewski <piotr.kliczewski(a)gmail.com>
8 years, 8 months
Change in vdsm[master]: sampling: move translation code into hoststats.py
by fromani@redhat.com
Francesco Romani has uploaded a new change for review.
Change subject: sampling: move translation code into hoststats.py
......................................................................
sampling: move translation code into hoststats.py
Move all the functions that produces host stats
from HostSamples into hoststats.py, like
we did for vmstats.py.
Note:
getBootTime() and get_boot_time() were moved
as well, even though they aren't translation
functions. Should they stay into sampling.py?
Change-Id: Icce6acbd596d087491678d039282d5d37d761904
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
---
M debian/vdsm.install
M tests/samplingTests.py
M vdsm.spec.in
M vdsm/virt/Makefile.am
A vdsm/virt/hoststats.py
M vdsm/virt/sampling.py
6 files changed, 222 insertions(+), 185 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/34/42034/1
diff --git a/debian/vdsm.install b/debian/vdsm.install
index ae35369..5d01712 100644
--- a/debian/vdsm.install
+++ b/debian/vdsm.install
@@ -148,6 +148,7 @@
./usr/share/vdsm/virt/__init__.py
./usr/share/vdsm/virt/domain_descriptor.py
./usr/share/vdsm/virt/guestagent.py
+./usr/share/vdsm/virt/hoststats.py
./usr/share/vdsm/virt/migration.py
./usr/share/vdsm/virt/periodic.py
./usr/share/vdsm/virt/sampling.py
diff --git a/tests/samplingTests.py b/tests/samplingTests.py
index 229d3d4..ab85834 100644
--- a/tests/samplingTests.py
+++ b/tests/samplingTests.py
@@ -28,7 +28,9 @@
from vdsm import ipwrapper
from vdsm.password import ProtectedPassword
+from virt import hoststats
import virt.sampling as sampling
+
import caps
@@ -80,39 +82,39 @@
shutil.rmtree(self._tmpDir)
def testBootTimeOk(self):
- with MonkeyPatchScope([(sampling, '_PROC_STAT_PATH',
+ with MonkeyPatchScope([(hoststats, '_PROC_STAT_PATH',
self._good_path)]):
- self.assertEquals(sampling.getBootTime(),
+ self.assertEquals(hoststats.getBootTime(),
1395249141)
def testBootTimeEmpty(self):
- with MonkeyPatchScope([(sampling, '_PROC_STAT_PATH',
+ with MonkeyPatchScope([(hoststats, '_PROC_STAT_PATH',
'/dev/null')]):
with self.assertRaises(ValueError):
- sampling.getBootTime()
+ hoststats.getBootTime()
def testBootTimeMissing(self):
- with MonkeyPatchScope([(sampling, '_PROC_STAT_PATH',
+ with MonkeyPatchScope([(hoststats, '_PROC_STAT_PATH',
self._missing_path)]):
with self.assertRaises(ValueError):
- sampling.getBootTime()
+ hoststats.getBootTime()
def testBootTimeMalformed(self):
- with MonkeyPatchScope([(sampling, '_PROC_STAT_PATH',
+ with MonkeyPatchScope([(hoststats, '_PROC_STAT_PATH',
self._malformed_path)]):
with self.assertRaises(ValueError):
- sampling.getBootTime()
+ hoststats.getBootTime()
def testBootTimeNonExistantFile(self):
- with MonkeyPatchScope([(sampling, '_PROC_STAT_PATH',
+ with MonkeyPatchScope([(hoststats, '_PROC_STAT_PATH',
'/i/do/not/exist/1234567890')]):
with self.assertRaises(IOError):
- sampling.getBootTime()
+ hoststats.getBootTime()
def testBootTimeExtra(self):
- with MonkeyPatchScope([(sampling, '_PROC_STAT_PATH',
+ with MonkeyPatchScope([(hoststats, '_PROC_STAT_PATH',
self._extra_path)]):
- self.assertEquals(sampling.getBootTime(), 1395249141)
+ self.assertEquals(hoststats.getBootTime(), 1395249141)
@contextmanager
@@ -336,7 +338,7 @@
with MonkeyPatchScope([(caps, 'getNumaTopology',
fakeNumaTopology)]):
self.assertEqual(
- sampling._get_cpu_core_stats(first_sample, last_sample),
+ hoststats._get_cpu_core_stats(first_sample, last_sample),
expected)
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 5c9061d..7d7abd2 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1000,6 +1000,7 @@
%{_datadir}/%{vdsm_name}/virt/__init__.py*
%{_datadir}/%{vdsm_name}/virt/domain_descriptor.py*
%{_datadir}/%{vdsm_name}/virt/guestagent.py*
+%{_datadir}/%{vdsm_name}/virt/hoststats.py*
%{_datadir}/%{vdsm_name}/virt/migration.py*
%{_datadir}/%{vdsm_name}/virt/periodic.py*
%{_datadir}/%{vdsm_name}/virt/sampling.py*
diff --git a/vdsm/virt/Makefile.am b/vdsm/virt/Makefile.am
index 376f973..88025be 100644
--- a/vdsm/virt/Makefile.am
+++ b/vdsm/virt/Makefile.am
@@ -27,6 +27,7 @@
__init__.py \
domain_descriptor.py \
guestagent.py \
+ hoststats.py \
migration.py \
periodic.py \
sampling.py \
diff --git a/vdsm/virt/hoststats.py b/vdsm/virt/hoststats.py
new file mode 100644
index 0000000..57c6954
--- /dev/null
+++ b/vdsm/virt/hoststats.py
@@ -0,0 +1,202 @@
+#
+# Copyright 2008-2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import logging
+
+from vdsm import utils
+
+import caps
+import v2v
+
+
+def produce(ncpus, first_sample, last_sample):
+ stats = _empty_stats()
+
+ if first_sample is None:
+ return stats
+
+ stats.update(_get_interfaces_stats(first_sample, last_sample))
+
+ interval = last_sample.timestamp - first_sample.timestamp
+
+ jiffies = (
+ last_sample.pidcpu.user - first_sample.pidcpu.user) % (2 ** 32)
+ stats['cpuUserVdsmd'] = jiffies / interval
+ jiffies = (
+ last_sample.pidcpu.sys - first_sample.pidcpu.sys) % (2 ** 32)
+ stats['cpuSysVdsmd'] = jiffies / interval
+
+ jiffies = (
+ last_sample.totcpu.user - first_sample.totcpu.user) % (2 ** 32)
+ stats['cpuUser'] = jiffies / interval / ncpus
+ jiffies = (
+ last_sample.totcpu.sys - first_sample.totcpu.sys) % (2 ** 32)
+ stats['cpuSys'] = jiffies / interval / ncpus
+ stats['cpuIdle'] = max(0.0,
+ 100.0 - stats['cpuUser'] - stats['cpuSys'])
+ stats['memUsed'] = last_sample.memUsed
+ stats['anonHugePages'] = last_sample.anonHugePages
+ stats['cpuLoad'] = last_sample.cpuLoad
+
+ stats['diskStats'] = last_sample.diskStats
+ stats['thpState'] = last_sample.thpState
+
+ if _boot_time():
+ stats['bootTime'] = _boot_time()
+
+ stats['numaNodeMemFree'] = last_sample.numaNodeMem.nodesMemSample
+ stats['cpuStatistics'] = _get_cpu_core_stats(
+ first_sample, last_sample)
+
+ stats['v2vJobs'] = v2v.get_jobs_status()
+ return stats
+
+
+_PROC_STAT_PATH = '/proc/stat'
+
+
+def getBootTime():
+ """
+ Returns the boot time of the machine in seconds since epoch.
+
+ Raises IOError if file access fails, or ValueError if boot time not
+ present in file.
+ """
+ with open(_PROC_STAT_PATH) as proc_stat:
+ for line in proc_stat:
+ if line.startswith('btime'):
+ parts = line.split()
+ if len(parts) > 1:
+ return int(parts[1])
+ else:
+ break
+ raise ValueError('Boot time not present')
+
+
+(a)utils.memoized
+def _boot_time():
+ # Try to get boot time only once, if N/A just log the error and never
+ # include it in the response.
+ try:
+ return getBootTime()
+ except (IOError, ValueError):
+ logging.exception('Failed to get boot time')
+ return None
+
+
+def _empty_stats():
+ return {
+ 'cpuUser': 0.0,
+ 'cpuSys': 0.0,
+ 'cpuIdle': 100.0,
+ 'rxRate': 0.0, # REQUIRED_FOR: engine < 3.6
+ 'txRate': 0.0, # REQUIRED_FOR: engine < 3.6
+ 'cpuSysVdsmd': 0.0,
+ 'cpuUserVdsmd': 0.0,
+ }
+
+
+def _get_cpu_core_stats(first_sample, last_sample):
+ interval = last_sample.timestamp - first_sample.timestamp
+
+ def compute_cpu_usage(cpu_core, mode):
+ jiffies = (
+ last_sample.cpuCores.getCoreSample(cpu_core)[mode] -
+ first_sample.cpuCores.getCoreSample(cpu_core)[mode]
+ ) % (2 ** 32)
+ return ("%.2f" % (jiffies / interval))
+
+ cpu_core_stats = {}
+ for node_index, numa_node in caps.getNumaTopology().iteritems():
+ cpu_cores = numa_node['cpus']
+ for cpu_core in cpu_cores:
+ core_stat = {
+ 'nodeIndex': int(node_index),
+ 'cpuUser': compute_cpu_usage(cpu_core, 'user'),
+ 'cpuSys': compute_cpu_usage(cpu_core, 'sys'),
+ }
+ core_stat['cpuIdle'] = (
+ "%.2f" % max(0.0,
+ 100.0 -
+ float(core_stat['cpuUser']) -
+ float(core_stat['cpuSys'])))
+ cpu_core_stats[str(cpu_core)] = core_stat
+ return cpu_core_stats
+
+
+def _get_interfaces_stats(first_sample, last_sample):
+ interval = last_sample.timestamp - first_sample.timestamp
+
+ rx = tx = rxDropped = txDropped = 0
+ stats = {'network': {}}
+ total_rate = 0
+ for ifid in last_sample.interfaces:
+ # it skips hot-plugged devices if we haven't enough information
+ # to count stats from it
+ if ifid not in first_sample.interfaces:
+ continue
+
+ ifrate = last_sample.interfaces[ifid].speed or 1000
+ Mbps2Bps = (10 ** 6) / 8
+ thisRx = (
+ last_sample.interfaces[ifid].rx -
+ first_sample.interfaces[ifid].rx
+ ) % (2 ** 32)
+ thisTx = (
+ last_sample.interfaces[ifid].tx -
+ first_sample.interfaces[ifid].tx
+ ) % (2 ** 32)
+ rxRate = 100.0 * thisRx / interval / ifrate / Mbps2Bps
+ txRate = 100.0 * thisTx / interval / ifrate / Mbps2Bps
+ if txRate > 100 or rxRate > 100:
+ txRate = min(txRate, 100.0)
+ rxRate = min(rxRate, 100.0)
+ logging.debug('Rate above 100%%.')
+ iface = last_sample.interfaces[ifid]
+ stats['network'][ifid] = {
+ 'name': ifid, 'speed': str(ifrate),
+ 'rxDropped': str(iface.rxDropped),
+ 'txDropped': str(iface.txDropped),
+ 'rxErrors': str(iface.rxErrors),
+ 'txErrors': str(iface.txErrors),
+ 'state': iface.operstate,
+ 'rxRate': '%.1f' % rxRate,
+ 'txRate': '%.1f' % txRate,
+ 'rx': str(iface.rx),
+ 'tx': str(iface.tx),
+ 'sampleTime': last_sample.timestamp,
+ }
+ rx += thisRx
+ tx += thisTx
+ rxDropped += last_sample.interfaces[ifid].rxDropped
+ txDropped += last_sample.interfaces[ifid].txDropped
+ total_rate += ifrate
+
+ total_bytes_per_sec = (total_rate or 1000) * (10 ** 6) / 8
+ stats['rxRate'] = 100.0 * rx / interval / total_bytes_per_sec
+ stats['txRate'] = 100.0 * tx / interval / total_bytes_per_sec
+ if stats['txRate'] > 100 or stats['rxRate'] > 100:
+ stats['txRate'] = min(stats['txRate'], 100.0)
+ stats['rxRate'] = min(stats['rxRate'], 100.0)
+ logging.debug(stats)
+ stats['rxDropped'] = rxDropped
+ stats['txDropped'] = txDropped
+
+ return stats
diff --git a/vdsm/virt/sampling.py b/vdsm/virt/sampling.py
index 38c5892..5729a54 100644
--- a/vdsm/virt/sampling.py
+++ b/vdsm/virt/sampling.py
@@ -35,9 +35,9 @@
from vdsm import netinfo
from vdsm import utils
from vdsm.config import config
-import v2v
from .utils import ExpiringCache
+from . import hoststats
import caps
@@ -196,27 +196,6 @@
class TimedSample(object):
def __init__(self):
self.timestamp = time.time()
-
-
-_PROC_STAT_PATH = '/proc/stat'
-
-
-def getBootTime():
- """
- Returns the boot time of the machine in seconds since epoch.
-
- Raises IOError if file access fails, or ValueError if boot time not
- present in file.
- """
- with open(_PROC_STAT_PATH) as proc_stat:
- for line in proc_stat:
- if line.startswith('btime'):
- parts = line.split()
- if len(parts) > 1:
- return int(parts[1])
- else:
- break
- raise ValueError('Boot time not present')
def _get_interfaces_and_samples():
@@ -590,158 +569,9 @@
if not self._stopEvent.isSet():
self._log.exception("Error while sampling stats")
- @utils.memoized
- def _boot_time(self):
- # Try to get boot time only once, if N/A just log the error and never
- # include it in the response.
- try:
- return getBootTime()
- except (IOError, ValueError):
- self._log.exception('Failed to get boot time')
- return None
-
def get(self):
- stats = self._empty_stats()
-
first_sample, last_sample, _ = self._samples.stats()
- if first_sample is None:
- return stats
-
- stats.update(_get_interfaces_stats(first_sample, last_sample))
-
- interval = last_sample.timestamp - first_sample.timestamp
-
- jiffies = (
- last_sample.pidcpu.user - first_sample.pidcpu.user) % (2 ** 32)
- stats['cpuUserVdsmd'] = jiffies / interval
- jiffies = (
- last_sample.pidcpu.sys - first_sample.pidcpu.sys) % (2 ** 32)
- stats['cpuSysVdsmd'] = jiffies / interval
-
- jiffies = (
- last_sample.totcpu.user - first_sample.totcpu.user) % (2 ** 32)
- stats['cpuUser'] = jiffies / interval / self._ncpus
- jiffies = (
- last_sample.totcpu.sys - first_sample.totcpu.sys) % (2 ** 32)
- stats['cpuSys'] = jiffies / interval / self._ncpus
- stats['cpuIdle'] = max(0.0,
- 100.0 - stats['cpuUser'] - stats['cpuSys'])
- stats['memUsed'] = last_sample.memUsed
- stats['anonHugePages'] = last_sample.anonHugePages
- stats['cpuLoad'] = last_sample.cpuLoad
-
- stats['diskStats'] = last_sample.diskStats
- stats['thpState'] = last_sample.thpState
-
- if self._boot_time():
- stats['bootTime'] = self._boot_time()
-
- stats['numaNodeMemFree'] = last_sample.numaNodeMem.nodesMemSample
- stats['cpuStatistics'] = _get_cpu_core_stats(
- first_sample, last_sample)
-
- stats['v2vJobs'] = v2v.get_jobs_status()
- return stats
-
- def _empty_stats(self):
- return {
- 'cpuUser': 0.0,
- 'cpuSys': 0.0,
- 'cpuIdle': 100.0,
- 'rxRate': 0.0, # REQUIRED_FOR: engine < 3.6
- 'txRate': 0.0, # REQUIRED_FOR: engine < 3.6
- 'cpuSysVdsmd': 0.0,
- 'cpuUserVdsmd': 0.0,
- }
-
-
-def _get_cpu_core_stats(first_sample, last_sample):
- interval = last_sample.timestamp - first_sample.timestamp
-
- def compute_cpu_usage(cpu_core, mode):
- jiffies = (
- last_sample.cpuCores.getCoreSample(cpu_core)[mode] -
- first_sample.cpuCores.getCoreSample(cpu_core)[mode]
- ) % (2 ** 32)
- return ("%.2f" % (jiffies / interval))
-
- cpu_core_stats = {}
- for node_index, numa_node in caps.getNumaTopology().iteritems():
- cpu_cores = numa_node['cpus']
- for cpu_core in cpu_cores:
- core_stat = {
- 'nodeIndex': int(node_index),
- 'cpuUser': compute_cpu_usage(cpu_core, 'user'),
- 'cpuSys': compute_cpu_usage(cpu_core, 'sys'),
- }
- core_stat['cpuIdle'] = (
- "%.2f" % max(0.0,
- 100.0 -
- float(core_stat['cpuUser']) -
- float(core_stat['cpuSys'])))
- cpu_core_stats[str(cpu_core)] = core_stat
- return cpu_core_stats
-
-
-def _get_interfaces_stats(first_sample, last_sample):
- interval = last_sample.timestamp - first_sample.timestamp
-
- rx = tx = rxDropped = txDropped = 0
- stats = {'network': {}}
- total_rate = 0
- for ifid in last_sample.interfaces:
- # it skips hot-plugged devices if we haven't enough information
- # to count stats from it
- if ifid not in first_sample.interfaces:
- continue
-
- ifrate = last_sample.interfaces[ifid].speed or 1000
- Mbps2Bps = (10 ** 6) / 8
- thisRx = (
- last_sample.interfaces[ifid].rx -
- first_sample.interfaces[ifid].rx
- ) % (2 ** 32)
- thisTx = (
- last_sample.interfaces[ifid].tx -
- first_sample.interfaces[ifid].tx
- ) % (2 ** 32)
- rxRate = 100.0 * thisRx / interval / ifrate / Mbps2Bps
- txRate = 100.0 * thisTx / interval / ifrate / Mbps2Bps
- if txRate > 100 or rxRate > 100:
- txRate = min(txRate, 100.0)
- rxRate = min(rxRate, 100.0)
- logging.debug('Rate above 100%%.')
- iface = last_sample.interfaces[ifid]
- stats['network'][ifid] = {
- 'name': ifid, 'speed': str(ifrate),
- 'rxDropped': str(iface.rxDropped),
- 'txDropped': str(iface.txDropped),
- 'rxErrors': str(iface.rxErrors),
- 'txErrors': str(iface.txErrors),
- 'state': iface.operstate,
- 'rxRate': '%.1f' % rxRate,
- 'txRate': '%.1f' % txRate,
- 'rx': str(iface.rx),
- 'tx': str(iface.tx),
- 'sampleTime': last_sample.timestamp,
- }
- rx += thisRx
- tx += thisTx
- rxDropped += last_sample.interfaces[ifid].rxDropped
- txDropped += last_sample.interfaces[ifid].txDropped
- total_rate += ifrate
-
- total_bytes_per_sec = (total_rate or 1000) * (10 ** 6) / 8
- stats['rxRate'] = 100.0 * rx / interval / total_bytes_per_sec
- stats['txRate'] = 100.0 * tx / interval / total_bytes_per_sec
- if stats['txRate'] > 100 or stats['rxRate'] > 100:
- stats['txRate'] = min(stats['txRate'], 100.0)
- stats['rxRate'] = min(stats['rxRate'], 100.0)
- logging.debug(stats)
- stats['rxDropped'] = rxDropped
- stats['txDropped'] = txDropped
-
- return stats
+ return hoststats.produce(self._ncpus, first_sample, last_sample)
def _getLinkSpeed(dev):
--
To view, visit https://gerrit.ovirt.org/42034
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Icce6acbd596d087491678d039282d5d37d761904
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
8 years, 8 months
Change in vdsm[master]: jsonrpc: increase call timeout to allow valid response
by ykaplan@redhat.com
Yeela Kaplan has uploaded a new change for review.
Change subject: jsonrpc: increase call timeout to allow valid response
......................................................................
jsonrpc: increase call timeout to allow valid response
Timeout of 15 seconds is too low,
and is causing tests to fail.
Need to increase to allow slow operations to complete.
Change-Id: I6a7a37a38d7bc9ddb3462c94ca0d5da122bedab3
Signed-off-by: Yeela Kaplan <ykaplan(a)redhat.com>
---
M lib/yajsonrpc/__init__.py
1 file changed, 1 insertion(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/50/46650/1
diff --git a/lib/yajsonrpc/__init__.py b/lib/yajsonrpc/__init__.py
index 03c49ed..4985074 100644
--- a/lib/yajsonrpc/__init__.py
+++ b/lib/yajsonrpc/__init__.py
@@ -26,7 +26,7 @@
__all__ = ["betterAsyncore", "stompreactor", "stomp"]
-CALL_TIMEOUT = 15
+CALL_TIMEOUT = 30
_STATE_INCOMING = 1
_STATE_OUTGOING = 2
--
To view, visit https://gerrit.ovirt.org/46650
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6a7a37a38d7bc9ddb3462c94ca0d5da122bedab3
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Yeela Kaplan <ykaplan(a)redhat.com>
8 years, 8 months
Change in vdsm[ovirt-3.5]: tests: Enable again utils.memoized in the tests
by fromani@redhat.com
Hello Nir Soffer, Dan Kenigsberg,
I'd like you to do a code review. Please visit
https://gerrit.ovirt.org/40030
to review the following change.
Change subject: tests: Enable again utils.memoized in the tests
......................................................................
tests: Enable again utils.memoized in the tests
Tests that may leave dirt in memoized functions should invalidate the
functions during teardown.
Since we disabled memoizing becuase of pulluted memoized functions in
caps module, caps tests invalidate all memoized functions now.
Change-Id: I019e2a2ad75973511cccd195a7e9eaa105d8154f
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/37841
Reviewed-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
Tested-by: Dan Kenigsberg <danken(a)redhat.com>
---
M tests/capsTests.py
M tests/testrunner.py
2 files changed, 7 insertions(+), 6 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/30/40030/1
diff --git a/tests/capsTests.py b/tests/capsTests.py
index e3f7d6a..d0ac3d5 100644
--- a/tests/capsTests.py
+++ b/tests/capsTests.py
@@ -41,6 +41,13 @@
class TestCaps(TestCaseBase):
+
+ def tearDown(self):
+ for name in dir(caps):
+ obj = getattr(caps, name)
+ if isinstance(obj, utils.memoized):
+ obj.invalidate()
+
def _readCaps(self, fileName):
testPath = os.path.realpath(__file__)
dirName = os.path.split(testPath)[0]
diff --git a/tests/testrunner.py b/tests/testrunner.py
index 13fe55e..37b4c95 100644
--- a/tests/testrunner.py
+++ b/tests/testrunner.py
@@ -411,10 +411,6 @@
raise AssertionError(msg)
-def fakeMemoized(func):
- return func
-
-
if __name__ == '__main__':
if "--help" in sys.argv:
print("testrunner options:\n"
@@ -426,6 +422,4 @@
# Mock panic() calls for tests
utils.panic = panicMock
- # Memoization during tests is a bad idea.
- utils.memoized = fakeMemoized
run()
--
To view, visit https://gerrit.ovirt.org/40030
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I019e2a2ad75973511cccd195a7e9eaa105d8154f
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Nir Soffer <nsoffer(a)redhat.com>
8 years, 8 months
Change in vdsm[ovirt-3.5]: utils: Add memoized invalidation
by fromani@redhat.com
Hello Piotr Kliczewski, Nir Soffer, Dan Kenigsberg,
I'd like you to do a code review. Please visit
https://gerrit.ovirt.org/40029
to review the following change.
Change subject: utils: Add memoized invalidation
......................................................................
utils: Add memoized invalidation
We learned in the hard way that memoizing and monkey-patching do work
nicely together. However, disabling memoizing during the tests means
that we do not test the same code in the application.
This patch adds invalidate() method to memoized functions, so tests can
clean up properly after they modify memozied data.
This can also be used by application code to invalidate memoized
functions in certain conditions.
Change-Id: I3053b8ecc567f7c3154f7473dfd6b587823313ae
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/37788
Reviewed-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-by: Piotr Kliczewski <piotr.kliczewski(a)gmail.com>
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M lib/vdsm/utils.py
M tests/utilsTests.py
2 files changed, 67 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/29/40029/1
diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index 4619b74..944cf4d 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -971,9 +971,14 @@
self.cache[args] = value
return value
+ def invalidate(self):
+ self.cache.clear()
+
def __get__(self, obj, objtype):
"""Support instance methods."""
- return functools.partial(self.__call__, obj)
+ wrapper = functools.partial(self.__call__, obj)
+ wrapper.invalidate = self.cache.clear
+ return wrapper
def validateMinimalKeySet(dictionary, reqParams):
diff --git a/tests/utilsTests.py b/tests/utilsTests.py
index 5b3614d..2a0b8ef 100644
--- a/tests/utilsTests.py
+++ b/tests/utilsTests.py
@@ -18,6 +18,7 @@
# Refer to the README and COPYING files for full details of the license
#
+import collections
import os.path
import contextlib
import errno
@@ -662,3 +663,63 @@
self.assertTrue(
hack < base/2,
"picklecopy [%f] not faster than deepcopy [%f]" % (hack, base))
+
+
+@expandPermutations
+class MemoizedTests(TestCaseBase):
+
+ def setUp(self):
+ self.values = {}
+ self.accessed = collections.defaultdict(int)
+
+ @permutations([[()], [("a",)], [("a", "b")]])
+ def test_memoized_method(self, args):
+ self.values[args] = 42
+ self.assertEqual(self.accessed[args], 0)
+ self.assertEqual(self.memoized_method(*args), 42)
+ self.assertEqual(self.accessed[args], 1)
+ self.assertEqual(self.memoized_method(*args), 42)
+ self.assertEqual(self.accessed[args], 1)
+
+ @permutations([[()], [("a",)], [("a", "b")]])
+ def test_memoized_function(self, args):
+ self.values[args] = 42
+ self.assertEqual(self.accessed[args], 0)
+ self.assertEqual(memoized_function(self, *args), 42)
+ self.assertEqual(self.accessed[args], 1)
+ self.assertEqual(memoized_function(self, *args), 42)
+ self.assertEqual(self.accessed[args], 1)
+
+ def test_key_error(self):
+ self.assertRaises(KeyError, self.memoized_method)
+ self.assertRaises(KeyError, self.memoized_method, "a")
+ self.assertRaises(KeyError, self.memoized_method, "a", "b")
+
+ def test_invalidate_method(self):
+ args = ("a",)
+ self.values[args] = 42
+ self.assertEqual(self.memoized_method(*args), 42)
+ self.memoized_method.invalidate()
+ self.assertEqual(self.memoized_method(*args), 42)
+ self.assertEqual(self.accessed[args], 2)
+
+ def test_invalidate_function(self):
+ args = ("a",)
+ self.values[args] = 42
+ self.assertEqual(memoized_function(self, *args), 42)
+ memoized_function.invalidate()
+ self.assertEqual(memoized_function(self, *args), 42)
+ self.assertEqual(self.accessed[args], 2)
+
+ @utils.memoized
+ def memoized_method(self, *args):
+ return self.get(args)
+
+ def get(self, key):
+ self.accessed[key] += 1
+ return self.values[key]
+
+
+(a)utils.memoized
+def memoized_function(test, *args):
+ return test.get(args)
--
To view, visit https://gerrit.ovirt.org/40029
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3053b8ecc567f7c3154f7473dfd6b587823313ae
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Nir Soffer <nsoffer(a)redhat.com>
Gerrit-Reviewer: Piotr Kliczewski <piotr.kliczewski(a)gmail.com>
8 years, 8 months
Change in vdsm[ovirt-3.5]: tests: disable memoization in testrunner
by fromani@redhat.com
Hello Nir Soffer, Dan Kenigsberg,
I'd like you to do a code review. Please visit
https://gerrit.ovirt.org/39949
to review the following change.
Change subject: tests: disable memoization in testrunner
......................................................................
tests: disable memoization in testrunner
memoization during tests is harmful, because
it adds another one hidden layer of global state
shared across test runs.
This may lead -and actually did- to hard
to debug failures in apparently unrelated code.
The net result is waste of developer's time,
and decreased trust in automated tests
because of mysterious failures.
To fix that, we now monkeypatch in testrunner
only utils.memoized with a fake which avoids caching.
Change-Id: Ibd986403a76268995b83c9e6ac400e942ed24cb6
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/37748
Reviewed-by: Nir Soffer <nsoffer(a)redhat.com>
Tested-by: Nir Soffer <nsoffer(a)redhat.com>
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M tests/testrunner.py
1 file changed, 6 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/49/39949/1
diff --git a/tests/testrunner.py b/tests/testrunner.py
index 37b4c95..13fe55e 100644
--- a/tests/testrunner.py
+++ b/tests/testrunner.py
@@ -411,6 +411,10 @@
raise AssertionError(msg)
+def fakeMemoized(func):
+ return func
+
+
if __name__ == '__main__':
if "--help" in sys.argv:
print("testrunner options:\n"
@@ -422,4 +426,6 @@
# Mock panic() calls for tests
utils.panic = panicMock
+ # Memoization during tests is a bad idea.
+ utils.memoized = fakeMemoized
run()
--
To view, visit https://gerrit.ovirt.org/39949
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibd986403a76268995b83c9e6ac400e942ed24cb6
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Nir Soffer <nsoffer(a)redhat.com>
8 years, 8 months
Change in vdsm[ovirt-3.5]: tests: clear libvirtconnection cache
by fromani@redhat.com
Hello Nir Soffer, Dan Kenigsberg,
I'd like you to do a code review. Please visit
https://gerrit.ovirt.org/39948
to review the following change.
Change subject: tests: clear libvirtconnection cache
......................................................................
tests: clear libvirtconnection cache
the libvirtconnection has a cache to reuse connections,
and this caching doesn't play well with the monkeypatching
which we do in tests.
In libvirtconnectionTests, we create fake libvirt objects,
most notably fake virConnect-s. Unfortunately, the test fails
to clean up properly the libvirtconnection cache.
So, the test runs just fine in isolation, but if run in batch
like in 'make check', later tests which expect the real object
become broken.
The failure presents itself like the following:
AttributeError: 'virConnect' object has no attribute 'getMemoryStats'
This patch fixes this error adding a facility to clear
the libvirtconnection cache, and clearing it after each
test.
Change-Id: If4d64920e5f26c276accf26b7a532461d04f02df
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
Reviewed-on: http://gerrit.ovirt.org/37747
Reviewed-by: Nir Soffer <nsoffer(a)redhat.com>
Reviewed-by: Dan Kenigsberg <danken(a)redhat.com>
---
M lib/vdsm/libvirtconnection.py
M tests/libvirtconnectionTests.py
2 files changed, 12 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/48/39948/1
diff --git a/lib/vdsm/libvirtconnection.py b/lib/vdsm/libvirtconnection.py
index b1332db..33fdf11 100644
--- a/lib/vdsm/libvirtconnection.py
+++ b/lib/vdsm/libvirtconnection.py
@@ -95,6 +95,14 @@
return utils.retry(libvirtOpen, timeout=10, sleep=0.2)
+def _clear():
+ """
+ For clearing connections during the tests.
+ """
+ with __connectionLock:
+ __connections.clear()
+
+
def get(target=None, killOnFailure=True):
"""Return current connection to libvirt or open a new one.
Use target to get/create the connection object linked to that object.
diff --git a/tests/libvirtconnectionTests.py b/tests/libvirtconnectionTests.py
index 1ac60a0..18e1984 100644
--- a/tests/libvirtconnectionTests.py
+++ b/tests/libvirtconnectionTests.py
@@ -103,6 +103,10 @@
class testLibvirtconnection(TestCaseBase):
+
+ def tearDown(self):
+ libvirtconnection._clear()
+
@MonkeyPatch(libvirtconnection, 'libvirt', LibvirtMock())
def testCallSucceeded(self):
"""Positive test - libvirtMock does not raise any errors"""
--
To view, visit https://gerrit.ovirt.org/39948
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If4d64920e5f26c276accf26b7a532461d04f02df
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken(a)redhat.com>
Gerrit-Reviewer: Nir Soffer <nsoffer(a)redhat.com>
8 years, 8 months
Change in vdsm[master]: move _kill_and_rm_pid to utils
by ibarkan@redhat.com
Ido Barkan has uploaded a new change for review.
Change subject: move _kill_and_rm_pid to utils
......................................................................
move _kill_and_rm_pid to utils
Further patches will use it in nettestlib.py
Change-Id: Ia459c02b63123dda081122a72b2517219978fc12
Signed-off-by: Ido Barkan <ibarkan(a)redhat.com>
---
M lib/vdsm/utils.py
M vdsm/network/configurators/dhclient.py
2 files changed, 15 insertions(+), 16 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/27/45527/1
diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index d847a23..e6ce981 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -1270,3 +1270,15 @@
log.debug("%s: %.2f seconds", message, elapsed)
else:
yield
+
+
+def kill_and_rm_pid(pid, pid_file):
+ try:
+ os.kill(pid, signal.SIGTERM)
+ except OSError as e:
+ if e.errno == os.errno.ESRCH: # Already exited
+ pass
+ else:
+ raise
+ if pid_file is not None:
+ rmFile(pid_file)
diff --git a/vdsm/network/configurators/dhclient.py b/vdsm/network/configurators/dhclient.py
index 181c302..0435584 100644
--- a/vdsm/network/configurators/dhclient.py
+++ b/vdsm/network/configurators/dhclient.py
@@ -22,7 +22,6 @@
import errno
import logging
import os
-import signal
import threading
from vdsm import cmdutils
@@ -31,7 +30,7 @@
from vdsm.utils import CommandPath
from vdsm.utils import execCmd
from vdsm.utils import pgrep
-from vdsm.utils import rmFile
+from vdsm.utils import kill_and_rm_pid
DHCLIENT_CGROUP = 'vdsm-dhclient'
LEASE_DIR = '/var/lib/dhclient'
@@ -90,7 +89,7 @@
else:
raise
else:
- _kill_and_rm_pid(pid, self.pidFile)
+ kill_and_rm_pid(pid, self.pidFile)
def kill_dhclient(device_name, family=4):
@@ -118,22 +117,10 @@
continue
logging.info('Stopping dhclient -%s before running our own on %s',
family, device_name)
- _kill_and_rm_pid(pid, pid_file)
+ kill_and_rm_pid(pid, pid_file)
# In order to be able to configure the device with dhclient again. It is
# necessary that dhclient does not find it configured with any IP address
# (except 0.0.0.0 which is fine, or IPv6 link-local address needed for
# DHCPv6).
ipwrapper.addrFlush(device_name, family)
-
-
-def _kill_and_rm_pid(pid, pid_file):
- try:
- os.kill(pid, signal.SIGTERM)
- except OSError as e:
- if e.errno == os.errno.ESRCH: # Already exited
- pass
- else:
- raise
- if pid_file is not None:
- rmFile(pid_file)
--
To view, visit https://gerrit.ovirt.org/45527
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia459c02b63123dda081122a72b2517219978fc12
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Ido Barkan <ibarkan(a)redhat.com>
8 years, 8 months
Change in vdsm[master]: net: qos: change top qos api
by ibarkan@redhat.com
Ido Barkan has uploaded a new change for review.
Change subject: net: qos: change top qos api
......................................................................
net: qos: change top qos api
Qos top api calls, configure_outbound and remove_outbound now take a
name of a physical device and a vlan_tag (that can be None). this
removes network object related code out of qos specific code and
simplifies unit testing.
Change-Id: Ie9c671cb0cf4b5e2e67b90861e2018c90f0f95f8
Signed-off-by: Ido Barkan <ibarkan(a)redhat.com>
---
M tests/tcTests.py
M vdsm/network/configurators/__init__.py
M vdsm/network/configurators/qos.py
3 files changed, 18 insertions(+), 21 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/26/45526/1
diff --git a/tests/tcTests.py b/tests/tcTests.py
index 53310a0..4ce6cd4 100644
--- a/tests/tcTests.py
+++ b/tests/tcTests.py
@@ -35,7 +35,7 @@
from nettestlib import Bridge, Dummy, Tap, vlan_device, requires_tc
from vdsm.constants import EXT_TC
-from network import api, tc
+from network import tc
from network.configurators import qos
@@ -384,8 +384,7 @@
self.device.remove()
def test_single_non_vlan(self):
- net_ent = api._objectivizeNetwork(nics=(self.device_name, ))
- qos.configure_outbound(HOST_QOS_OUTBOUND, top_device=net_ent)
+ qos.configure_outbound(HOST_QOS_OUTBOUND, self.device_name, None)
tc_classes, tc_filters, tc_qdiscs = \
self._analise_qos_and_general_assertions()
self.assertEqual(tc_classes.classes, [])
@@ -400,10 +399,9 @@
@permutations([[1], [2]])
def test_single_vlan(self, repeating_calls):
with vlan_device(self.device_name) as vlan:
- net_ent = api._objectivizeNetwork(vlan_id=vlan.tag,
- nics=(self.device_name, ))
for _ in xrange(repeating_calls):
- qos.configure_outbound(HOST_QOS_OUTBOUND, top_device=net_ent)
+ qos.configure_outbound(HOST_QOS_OUTBOUND, self.device_name,
+ vlan.tag)
tc_classes, tc_filters, tc_qdiscs = \
self._analise_qos_and_general_assertions()
self.assertEqual(len(tc_classes.classes), 1)
@@ -421,10 +419,8 @@
with vlan_device(self.device_name, 16) as vlan1:
with vlan_device(self.device_name, 17) as vlan2:
for v in (vlan1, vlan2):
- net_ent = api._objectivizeNetwork(
- vlan_id=v.tag, nics=(self.device_name, ))
qos.configure_outbound(HOST_QOS_OUTBOUND,
- top_device=net_ent)
+ self.device_name, v.tag)
tc_classes, tc_filters, tc_qdiscs = \
self._analise_qos_and_general_assertions()
diff --git a/vdsm/network/configurators/__init__.py b/vdsm/network/configurators/__init__.py
index bca3eba..44107ee 100644
--- a/vdsm/network/configurators/__init__.py
+++ b/vdsm/network/configurators/__init__.py
@@ -30,7 +30,7 @@
from .dhclient import DhcpClient
from ..errors import ConfigNetworkError, ERR_FAILED_IFUP
from . import qos
-from ..models import Bond, Bridge
+from ..models import Bond, Bridge, hierarchy_vlan_tag, hierarchy_backing_device
from ..sourceroute import StaticSourceRoute
@@ -116,10 +116,14 @@
def configureQoS(self, hostQos, top_device):
out = hostQos.get('out')
if out is not None:
- qos.configure_outbound(out, top_device)
+ device = hierarchy_backing_device(top_device).name
+ vlan_tag = hierarchy_vlan_tag(top_device)
+ qos.configure_outbound(out, device, vlan_tag)
def removeQoS(self, top_device):
- qos.remove_outbound(top_device)
+ device = hierarchy_backing_device(top_device).name
+ vlan_tag = hierarchy_vlan_tag(top_device)
+ qos.remove_outbound(device, vlan_tag)
def _addSourceRoute(self, netEnt):
ipv4 = netEnt.ipv4
diff --git a/vdsm/network/configurators/qos.py b/vdsm/network/configurators/qos.py
index 25d049f..7806239 100644
--- a/vdsm/network/configurators/qos.py
+++ b/vdsm/network/configurators/qos.py
@@ -24,7 +24,6 @@
from vdsm import netinfo
from .. import tc
-from .. import models
_NON_VLANNED_ID = 5000
_DEFAULT_CLASSID = '%x' % _NON_VLANNED_ID
_ROOT_QDISC_HANDLE = '%x:' % 5001 # Leave 0 free for leaf qdisc of vlan tag 0
@@ -33,11 +32,10 @@
_SHAPING_QDISC_KIND = 'hfsc'
-def configure_outbound(qosOutbound, top_device):
+def configure_outbound(qosOutbound, device, vlan_tag):
"""Adds the qosOutbound configuration to the backing device (be it bond
- or nic). Adds a class and filter for default traffic if necessary"""
- vlan_tag = models.hierarchy_vlan_tag(top_device)
- device = models.hierarchy_backing_device(top_device).name
+ or nic). Adds a class and filter for default traffic if necessary. vlan_tag
+ can be None"""
root_qdisc = _root_qdisc(tc._qdiscs(device))
class_id = '%x' % (_NON_VLANNED_ID if vlan_tag is None else vlan_tag)
if not root_qdisc or root_qdisc['kind'] != _SHAPING_QDISC_KIND:
@@ -47,11 +45,10 @@
qosOutbound)
-def remove_outbound(top_device):
+def remove_outbound(device, vlan_tag):
"""Removes the qosOutbound configuration from the device and restores
- pfifo_fast if it was the last QoSed network on the device"""
- vlan_tag = models.hierarchy_vlan_tag(top_device)
- device = models.hierarchy_backing_device(top_device).name
+ pfifo_fast if it was the last QoSed network on the device. vlan_tag
+ can be None"""
class_id = '%x' % (_NON_VLANNED_ID if vlan_tag is None else vlan_tag)
MISSING_OBJ_ERR_CODES = (errno.EINVAL, errno.ENOENT, errno.EOPNOTSUPP)
--
To view, visit https://gerrit.ovirt.org/45526
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie9c671cb0cf4b5e2e67b90861e2018c90f0f95f8
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Ido Barkan <ibarkan(a)redhat.com>
8 years, 8 months
Change in vdsm[master]: net: tests: wip first real tc test
by ibarkan@redhat.com
Ido Barkan has uploaded a new change for review.
Change subject: net: tests: wip first real tc test
......................................................................
net: tests: wip first real tc test
Change-Id: Ibad639a9ad04593cfd477f60a8272614f3446522
Signed-off-by: Ido Barkan <ibarkan(a)redhat.com>
---
M tests/tcTests.py
1 file changed, 25 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/99/44699/1
diff --git a/tests/tcTests.py b/tests/tcTests.py
index e84d96c..c17df93 100644
--- a/tests/tcTests.py
+++ b/tests/tcTests.py
@@ -30,10 +30,11 @@
from testlib import VdsmTestCase as TestCaseBase
from testValidation import ValidateRunningAsRoot
-from nettestlib import Bridge, Tap, requires_brctl, requires_tc
+from nettestlib import Bridge, Dummy, Tap, requires_tc
from vdsm.constants import EXT_TC
from network import tc
+from network.configurators import qos
class TestQdisc(TestCaseBase):
@@ -352,3 +353,26 @@
tc.setPortMirroring(self._bridge0.devName, self._bridge2.devName)
self.testMirroring()
tc.unsetPortMirroring(self._bridge0.devName, self._bridge2.devName)
+
+
+class TestConfigureOutbound(TestCaseBase):
+ def setUp(self):
+ self.device = Dummy()
+ self.device.create()
+
+ # TODO:
+ # test with/without vlan (see filters are right) and classes are on correct
+ # devices (use tc.filters/tc.classes for this)
+
+ def tearDown(self):
+ self.device.remove()
+
+ def test_sanity(self):
+ host_qos_outbound = {
+ 'ls': {
+ 'm1': 4 * 1000 ** 2, # 4Mbit/s
+ 'd': 100 * 1000, # 100 microseconds
+ 'm2': 3 * 1000 ** 2}, # 3Mbit/s
+ 'ul': {
+ 'm2': 8 * 1000 ** 2}} # 8Mbit/s
+ qos.configure_outbound(host_qos_outbound, top_device=self.device)
\ No newline at end of file
--
To view, visit https://gerrit.ovirt.org/44699
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibad639a9ad04593cfd477f60a8272614f3446522
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Ido Barkan <ibarkan(a)redhat.com>
8 years, 8 months