How to use keyvalue method in tox

Best Python code snippet using tox_python

cpu_monitor.py

Source:cpu_monitor.py Github

copy

Full Screen

1#!/usr/bin/env python2#3# Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)4#5# Licensed under the Apache License, Version 2.0 (the "License");6# you may not use this file except in compliance with the License.7# You may obtain a copy of the License at8#9# http://www.apache.org/licenses/LICENSE-2.010#11# Unless required by applicable law or agreed to in writing, software12# distributed under the License is distributed on an "AS IS" BASIS,13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.14# See the License for the specific language governing permissions and15# limitations under the License.16import sys17import traceback18import socket19import psutil20import numpy as np21import math22import rospy23from diagnostic_msgs.msg import DiagnosticArray, DiagnosticStatus, KeyValue24from netdata_tools.netdata_tools import query_netdata_info, query_netdata25stat_dict = { DiagnosticStatus.OK: 'OK', DiagnosticStatus.WARN: 'Warning', DiagnosticStatus.ERROR: 'Error', DiagnosticStatus.STALE: 'Stale' }26class CPUMonitor():27 def __init__(self, hostname, diag_hostname):28 self._check_core_temps = rospy.get_param('~check_core_temps', False)29 self._core_load_warn = rospy.get_param('~core_load_warn', 90)30 self._core_load_error = rospy.get_param('~core_load_error', 110)31 self._load1_threshold = rospy.get_param('~load1_threshold', 5.0)32 self._load5_threshold = rospy.get_param('~load5_threshold', 3.0)33 self._core_temp_warn = rospy.get_param('~core_temp_warn', 90)34 self._core_temp_error = rospy.get_param('~core_temp_error', 95)35 self._mem_warn = rospy.get_param('~mem_warn', 25)36 self._mem_error = rospy.get_param('~mem_error', 1)37 self._check_thermal_throttling_events = rospy.get_param('~check_thermal_throttling_events', False)38 self._thermal_throttling_threshold = rospy.get_param('~thermal_throttling_threshold', 1000)39 self._check_idlejitter = rospy.get_param('~check_idlejitter', False)40 self._idlejitter_min_threshold = rospy.get_param('~idlejitter_min_threshold', 50000)41 self._idlejitter_max_threshold = rospy.get_param('~idlejitter_max_threshold', 2000000)42 self._idlejitter_average_threshold = rospy.get_param('~idlejitter_average_threshold', 200000)43 self._num_cores = rospy.get_param('~num_cores', psutil.cpu_count())44 # CPU stats45 self._info_stat = DiagnosticStatus()46 self._info_stat.name = '%s CPU Info' % diag_hostname47 self._info_stat.level = DiagnosticStatus.WARN48 self._info_stat.hardware_id = hostname49 self._info_stat.message = 'No Data'50 self._info_stat.values = []51 self._usage_stat = DiagnosticStatus()52 self._usage_stat.name = '%s CPU Usage' % diag_hostname53 self._usage_stat.level = DiagnosticStatus.WARN54 self._usage_stat.hardware_id = hostname55 self._usage_stat.message = 'No Data'56 self._usage_stat.values = []57 self._memory_stat = DiagnosticStatus()58 self._memory_stat.name = '%s Memory Usage' % diag_hostname59 self._memory_stat.level = DiagnosticStatus.WARN60 self._memory_stat.hardware_id = hostname61 self._memory_stat.message = 'No Data'62 self._memory_stat.values = []63 self._diag_pub = rospy.Publisher('/diagnostics', DiagnosticArray, queue_size=1)64 self._publish_timer = rospy.Timer(rospy.Duration(1.0), self.publish_stats)65 self._info_timer = rospy.Timer(rospy.Duration(5.0), self.check_info)66 self._usage_timer = rospy.Timer(rospy.Duration(5.0), self.check_usage)67 self._memory_timer = rospy.Timer(rospy.Duration(5.0), self.check_memory)68 ##\brief Check CPU core temps69 def check_core_temps(self, interval=1):70 diag_vals = []71 diag_msgs = []72 diag_level = DiagnosticStatus.OK73 try:74 # _ vs -75 netdata_module_name_core_temps = ['sensors.coretemp_isa_0000_temperature',76 'sensors.coretemp-isa-0000_temperature']77 for name in netdata_module_name_core_temps:78 netdata_core_temp, error = query_netdata(name, interval)79 if netdata_core_temp:80 break81 if not netdata_core_temp:82 diag_level = DiagnosticStatus.ERROR83 diag_msgs = [ 'Core Temp Error' ]84 diag_vals = [ KeyValue(key = 'Core Temp Error', value = 'Could not fetch data from netdata'),85 KeyValue(key = 'Output', value = netdata_core_temp),86 KeyValue(key = 'Error', value= error) ]87 return (diag_vals, diag_msgs, diag_level)88 del netdata_core_temp['time']89 del netdata_core_temp['Package id 0']90 for core_no, values in netdata_core_temp.items():91 mean_temp = np.mean(values)92 try:93 diag_vals.append(KeyValue(key = 'Temp %s' % core_no, value = str(mean_temp)))94 if mean_temp >= self._core_temp_error:95 diag_level = max(diag_level, DiagnosticStatus.OK) #do not set ERROR96 diag_msgs.append('CPU Hot')97 elif mean_temp >= self._core_temp_warn:98 diag_level = max(diag_level, DiagnosticStatus.OK) #do not set WARN99 diag_msgs.append('CPU Warm')100 except ValueError:101 diag_level = max(diag_level, DiagnosticStatus.ERROR) # Error if not numeric value102 diag_vals.append(KeyValue(key = 'Temp %s' % core_no, value = str(mean_temp)))103 except Exception as e:104 diag_level = DiagnosticStatus.ERROR105 diag_msgs = [ 'Core Temp Exception' ]106 diag_vals = [ KeyValue(key = 'Exception', value = str(e)), KeyValue(key = 'Traceback', value = str(traceback.format_exc())) ]107 return diag_vals, diag_msgs, diag_level108 ##\brief Checks clock speed from reading from CPU info109 def check_clock_speed(self, interval=1):110 diag_vals = []111 diag_msgs = []112 diag_level = DiagnosticStatus.OK113 try:114 netdata_cpu_freq, error = query_netdata('cpu.cpufreq', interval)115 if not netdata_cpu_freq:116 diag_level = DiagnosticStatus.ERROR117 diag_msgs = [ 'Clock Speed Error' ]118 diag_vals = [ KeyValue(key = 'Clock Speed Error', value = 'Could not fetch data from netdata'),119 KeyValue(key = 'Output', value = netdata_cpu_freq),120 KeyValue(key = 'Error', value= error) ]121 return (diag_vals, diag_msgs, diag_level)122 del netdata_cpu_freq["time"]123 for cpu_name, values in netdata_cpu_freq.items():124 diag_vals.append(KeyValue(key = 'Core %d (MHz)' % int(cpu_name[-1]), value = str(np.mean(values))))125 # get max freq126 netdata_info, error = query_netdata_info()127 if not netdata_info:128 diag_level = DiagnosticStatus.ERROR129 diag_msgs = [ 'Clock Speed Error' ]130 diag_vals = [ KeyValue(key = 'Clock Speed Error', value = 'Could not fetch data from netdata'),131 KeyValue(key = 'Output', value = netdata_info),132 KeyValue(key = 'Error', value= error) ]133 return (diag_vals, diag_msgs, diag_level)134 max_cpu_freq = float(netdata_info['cpu_freq'])/1e6135 diag_vals.append(KeyValue(key = 'Maximum Frequency (MHz)', value = str(max_cpu_freq)))136 except Exception as e:137 diag_level = DiagnosticStatus.ERROR138 diag_msgs = [ 'Clock Speed Exception' ]139 diag_vals = [ KeyValue(key = 'Exception', value = str(e)), KeyValue(key = 'Traceback', value = str(traceback.format_exc())) ]140 return diag_vals, diag_msgs, diag_level141 ##\brief Uses 'uptime' to see system uptime142 def check_uptime(self, interval=1):143 diag_vals = []144 diag_msg = ''145 diag_level = DiagnosticStatus.OK146 try:147 netdata_uptime, error = query_netdata('system.uptime', interval)148 if not netdata_uptime:149 diag_level = DiagnosticStatus.ERROR150 diag_msg = 'Uptime Error'151 diag_vals = [ KeyValue(key = 'Uptime Error', value = 'Could not fetch data from netdata'),152 KeyValue(key = 'Output', value = netdata_uptime),153 KeyValue(key = 'Error', value= error) ]154 return (diag_vals, diag_msg, diag_level)155 del netdata_uptime['time']156 diag_vals.append(KeyValue(key = 'Uptime', value = str(np.max(netdata_uptime['uptime'].astype(float)))))157 except Exception as e:158 diag_level = DiagnosticStatus.ERROR159 diag_msg = 'Uptime Exception'160 diag_vals = [ KeyValue(key = 'Exception', value = str(e)), KeyValue(key = 'Traceback', value = str(traceback.format_exc())) ]161 return diag_vals, diag_msg, diag_level162 ##\brief Uses 'system.load' to see load average163 def check_load(self, interval=1):164 diag_vals = []165 diag_msg = ''166 diag_level = DiagnosticStatus.OK167 load_dict = { DiagnosticStatus.OK: 'OK', DiagnosticStatus.WARN: 'High Load', DiagnosticStatus.ERROR: 'Very High Load' }168 try:169 netdata_cpu_load, error = query_netdata('system.load', interval)170 if not netdata_cpu_load:171 diag_level = DiagnosticStatus.ERROR172 diag_msg = 'Load Error'173 diag_vals = [ KeyValue(key = 'Load Error', value = 'Could not fetch data from netdata'),174 KeyValue(key = 'Output', value = netdata_cpu_load),175 KeyValue(key = 'Error', value= error) ]176 return (diag_vals, diag_msg, diag_level)177 del netdata_cpu_load['time']178 load1 = np.mean(netdata_cpu_load['load1'].astype(float))179 load5 = np.mean(netdata_cpu_load['load5'].astype(float))180 load15 = np.mean(netdata_cpu_load['load15'].astype(float))181 # Give warning if we go over load limit182 if float(load1) > self._load1_threshold or float(load5) > self._load5_threshold:183 diag_level = DiagnosticStatus.WARN184 diag_vals.append(KeyValue(key = 'Load Average Status', value = load_dict[diag_level]))185 diag_vals.append(KeyValue(key = '1 min Load Average', value = str(load1)))186 diag_vals.append(KeyValue(key = '1 min Load Average Threshold', value = str(self._load1_threshold)))187 diag_vals.append(KeyValue(key = '5 min Load Average', value = str(load5)))188 diag_vals.append(KeyValue(key = '5 min Load Average Threshold', value = str(self._load5_threshold)))189 diag_vals.append(KeyValue(key = '15 min Load Average', value = str(load15)))190 diag_msg = load_dict[diag_level]191 except Exception as e:192 diag_level = DiagnosticStatus.ERROR193 diag_msg = 'Load Exception'194 diag_vals = [ KeyValue(key = 'Exception', value = str(e)), KeyValue(key = 'Traceback', value = str(traceback.format_exc())) ]195 return diag_vals, diag_msg, diag_level196 ##\brief Uses 'free -m' to check free memory197 def check_free_memory(self, interval=1):198 diag_vals = []199 diag_msg = ''200 diag_level = DiagnosticStatus.OK201 mem_dict = { DiagnosticStatus.OK: 'OK', DiagnosticStatus.WARN: 'Low Memory', DiagnosticStatus.ERROR: 'Very Low Memory' }202 try:203 netdata_mem, error = query_netdata('system.ram', interval)204 if not netdata_mem:205 diag_level = DiagnosticStatus.ERROR206 diag_msg = 'Memory Usage Error'207 diag_vals = [ KeyValue(key = 'Memory Usage Error', value = 'Could not fetch data from netdata'),208 KeyValue(key = 'Output', value = netdata_mem),209 KeyValue(key = 'Error', value= error) ]210 return (diag_vals, diag_msg, diag_level)211 del netdata_mem['time']212 # Mem213 memory_vals = {k: np.mean(v.astype(float)) for k, v in netdata_mem.items()}214 total_mem = sum([val for val in memory_vals.values()])215 free_mem = memory_vals['free']216 used_mem = memory_vals['used']217 cache_mem = memory_vals['cached'] + memory_vals['buffers']218 diag_level = DiagnosticStatus.OK219 if float(free_mem) < self._mem_warn:220 diag_level = DiagnosticStatus.WARN221 if float(free_mem) < self._mem_error:222 diag_level = DiagnosticStatus.ERROR223 diag_vals.append(KeyValue(key = 'Mem Status', value = mem_dict[diag_level]))224 diag_vals.append(KeyValue(key = 'Mem Total', value = str(total_mem)))225 diag_vals.append(KeyValue(key = 'Mem Used', value = str(used_mem)))226 diag_vals.append(KeyValue(key = 'Mem Free', value = str(free_mem)))227 diag_vals.append(KeyValue(key = 'Mem Buff/Cache', value = str(cache_mem)))228 netdata_swp, error = query_netdata('system.swap', interval)229 if not netdata_swp:230 diag_level = DiagnosticStatus.ERROR231 diag_msg = 'Swap Usage Error'232 diag_vals = [ KeyValue(key = 'Swap Usage Error', value = 'Could not fetch data from netdata'),233 KeyValue(key = 'Output', value = netdata_swp),234 KeyValue(key = 'Error', value= error) ]235 return (diag_vals, diag_msg, diag_level)236 del netdata_swp['time']237 # Swap238 swap_vals = {k: np.mean(v.astype(float)) for k, v in netdata_swp.items()}239 total_swp = sum([val for val in swap_vals.values()])240 free_swp = swap_vals['free']241 used_swp = swap_vals['used']242 diag_vals.append(KeyValue(key = 'Swap Total', value = str(total_swp)))243 diag_vals.append(KeyValue(key = 'Swap Used', value = str(used_swp)))244 diag_vals.append(KeyValue(key = 'Swap Free', value = str(free_swp)))245 diag_msg = mem_dict[diag_level]246 except Exception as e:247 diag_level = DiagnosticStatus.ERROR248 diag_msg = 'Memory Usage Exception'249 diag_vals = [ KeyValue(key = 'Exception', value = str(e)), KeyValue(key = 'Traceback', value = str(traceback.format_exc())) ]250 return diag_vals, diag_msg, diag_level251 def check_cpu_util(self, interval=1):252 diag_vals = []253 diag_msg = ''254 diag_level = DiagnosticStatus.OK255 load_dict = { DiagnosticStatus.OK: 'OK', DiagnosticStatus.WARN: 'High Load', DiagnosticStatus.ERROR: 'Error' }256 try:257 netdata_info, error = query_netdata_info()258 if not netdata_info:259 diag_level = DiagnosticStatus.ERROR260 diag_msg = 'CPU Usage Error'261 diag_vals = [ KeyValue(key = 'CPU Usage Error', value = 'Could not fetch data from netdata'),262 KeyValue(key = 'Output', value = netdata_info),263 KeyValue(key = 'Error', value= error) ]264 return (diag_vals, diag_msg, diag_level)265 num_cores = int(netdata_info['cores_total'])266 netdata_system_cpu, error = query_netdata('system.cpu', interval)267 if not netdata_system_cpu:268 diag_level = DiagnosticStatus.ERROR269 diag_msg = 'CPU Usage Error'270 diag_vals = [ KeyValue(key = 'CPU Usage Error', value = 'Could not fetch data from netdata'),271 KeyValue(key = 'Output', value = netdata_system_cpu),272 KeyValue(key = 'Error', value= error) ]273 return (diag_vals, diag_msg, diag_level)274 netdata_cpu_util = [query_netdata('cpu.cpu%d' % i, interval) for i in range(num_cores)]275 netdata_cpu_idle = [query_netdata('cpu.cpu%d_cpuidle' % i, interval) for i in range(num_cores)]276 if any([data == None for data, error in netdata_cpu_util]):277 diag_level = DiagnosticStatus.ERROR278 diag_msg = 'CPU Util Error'279 diag_vals = [ KeyValue(key = 'CPU Util Error', value = 'Could not fetch data from netdata'),280 KeyValue(key = 'Output', value = netdata_cpu_util) ]281 return (diag_vals, diag_msg, diag_level)282 if any([data == None for data, error in netdata_cpu_idle]):283 diag_level = DiagnosticStatus.ERROR284 diag_msg = 'CPU Idle Error'285 diag_vals = [ KeyValue(key = 'CPU Idle Error', value = 'Could not fetch data from netdata'),286 KeyValue(key = 'Output', value = netdata_cpu_idle) ]287 return (diag_vals, diag_msg, diag_level)288 cores_loaded = 0289 for i_cpu in range(num_cores):290 cpu_name = 'Core %d' % (i_cpu)291 idle = 100 - np.mean(netdata_cpu_idle[i_cpu][0]['C0 (active)'])292 user = np.mean(netdata_cpu_util[i_cpu][0]['user'])293 nice = np.mean(netdata_cpu_util[i_cpu][0]['nice'])294 system = np.mean(netdata_cpu_util[i_cpu][0]['system'])295 core_level = DiagnosticStatus.OK296 usage = float(user) + float(nice)297 if usage > self._core_load_warn:298 cores_loaded += 1299 core_level = DiagnosticStatus.WARN300 if usage > self._core_load_error:301 core_level = DiagnosticStatus.ERROR302 diag_vals.append(KeyValue(key = 'CPU %s Status' % cpu_name, value = load_dict[core_level]))303 diag_vals.append(KeyValue(key = 'CPU %s User' % cpu_name, value = str(user)))304 diag_vals.append(KeyValue(key = 'CPU %s Nice' % cpu_name, value = str(nice)))305 diag_vals.append(KeyValue(key = 'CPU %s System' % cpu_name, value = str(system)))306 diag_vals.append(KeyValue(key = 'CPU %s Idle' % cpu_name, value = str(idle)))307 # Warn for high load only if we have <= 2 cores that aren't loaded308 if num_cores - cores_loaded <= 2 and num_cores > 2:309 diag_level = DiagnosticStatus.WARN310 diag_msg = load_dict[diag_level]311 except Exception as e:312 diag_level = DiagnosticStatus.ERROR313 diag_msg = 'CPU Usage Exception'314 diag_vals = [ KeyValue(key = 'Exception', value = str(e)), KeyValue(key = 'Traceback', value = str(traceback.format_exc())) ]315 return diag_vals, diag_msg, diag_level316 def check_core_throttling(self, interval=1):317 throt_dict = {DiagnosticStatus.OK: 'OK', DiagnosticStatus.WARN: 'High Thermal Throttling Events',318 DiagnosticStatus.ERROR: 'No valid Data from NetData'}319 throt_level = DiagnosticStatus.OK320 throt_vals = []321 netdata, error = query_netdata('cpu.core_throttling', interval)322 if not netdata:323 diag_level = DiagnosticStatus.ERROR324 diag_msg = 'Core Throttling Error'325 diag_vals = [ KeyValue(key = 'Core Throttling Error', value = 'Could not fetch data from netdata'),326 KeyValue(key = 'Output', value = netdata),327 KeyValue(key = 'Error', value= error) ]328 return (diag_vals, diag_msg, diag_level)329 for i in range(self._num_cores):330 lbl = 'CPU %d Thermal Throttling Events' % i331 netdata_key = 'cpu%d' % i332 core_mean = 'N/A'333 if netdata_key in netdata:334 core_data = netdata[netdata_key]335 if core_data is not None:336 core_mean = np.mean(core_data)337 if core_mean > self._thermal_throttling_threshold:338 throt_level = DiagnosticStatus.WARN339 else:340 throt_level = DiagnosticStatus.ERROR341 throt_vals.append(KeyValue(key=lbl, value='%r' % core_mean))342 throt_vals.insert(0, KeyValue(key='Thermal Throttling Status', value=throt_dict[throt_level]))343 throt_vals.append(KeyValue(key='Thermal Throttling Threshold', value=str(self._thermal_throttling_threshold)))344 return throt_vals, throt_dict[throt_level], throt_level345 def check_idlejitter(self, interval=1):346 jitter_dict = {DiagnosticStatus.OK: 'OK', DiagnosticStatus.WARN: 'High IDLE Jitter',347 DiagnosticStatus.ERROR: 'No valid Data from NetData'}348 jitter_level = DiagnosticStatus.OK349 jitter_vals = []350 netdata, error = query_netdata('system.idlejitter', interval)351 if not netdata:352 diag_level = DiagnosticStatus.ERROR353 diag_msg = 'Core Throttling Error'354 diag_vals = [ KeyValue(key = 'Core Throttling Error', value = 'Could not fetch data from netdata'),355 KeyValue(key = 'Output', value = netdata),356 KeyValue(key = 'Error', value= error) ]357 return (diag_vals, diag_msg, diag_level)358 metric_list = [359 ('IDLE Jitter Min', 'min', self._idlejitter_min_threshold, np.min),360 ('IDLE Jitter Max', 'max', self._idlejitter_max_threshold, np.max),361 ('IDLE Jitter Average', 'average', self._idlejitter_average_threshold, np.mean),362 ]363 for metric_label, metric_key, metric_threshold, aggregate_fnc in metric_list:364 metric_aggreagte = 'N/A'365 if netdata is not None and metric_key in netdata:366 metric_data = netdata[metric_key]367 if metric_data is not None:368 metric_aggreagte = aggregate_fnc(metric_data)369 if metric_aggreagte > metric_threshold:370 jitter_level = DiagnosticStatus.WARN371 else:372 jitter_level = DiagnosticStatus.ERROR373 jitter_vals.append(KeyValue(key=metric_label, value=str(metric_aggreagte)))374 jitter_vals.append(KeyValue(key=metric_label + ' Threshold', value=str(metric_threshold)))375 jitter_vals.insert(0, KeyValue(key='IDLE Jitter Status', value=jitter_dict[jitter_level]))376 return jitter_vals, jitter_dict[jitter_level], jitter_level377 def check_info(self, event):378 diag_vals = []379 diag_msgs = []380 diag_level = DiagnosticStatus.OK381 if self._check_core_temps:382 interval = math.ceil(self._usage_timer._period.to_sec())383 core_vals, core_msgs, core_level = self.check_core_temps(interval=interval)384 diag_vals.extend(core_vals)385 diag_msgs.extend(core_msgs)386 diag_level = max(diag_level, core_level)387 clock_vals, clock_msgs, clock_level = self.check_clock_speed()388 diag_vals.extend(clock_vals)389 diag_msgs.extend(clock_msgs)390 diag_level = max(diag_level, clock_level)391 diag_log = set(diag_msgs)392 if len(diag_log) > DiagnosticStatus.OK:393 message = ', '.join(diag_log)394 else:395 message = stat_dict[diag_level]396 self._info_stat.values = diag_vals397 self._info_stat.message = message398 self._info_stat.level = diag_level399 def check_usage(self, event):400 diag_vals = []401 diag_msgs = []402 diag_level = DiagnosticStatus.OK403 interval = math.ceil(self._usage_timer._period.to_sec())404 # Check mpstat405 mp_vals, mp_msg, mp_level = self.check_cpu_util(interval=interval)406 diag_vals.extend(mp_vals)407 if mp_level > DiagnosticStatus.OK:408 diag_msgs.append(mp_msg)409 diag_level = max(diag_level, mp_level)410 # Check NetData cpu.core_throttling411 if self._check_thermal_throttling_events:412 throt_vals, throt_msg, throt_level = self.check_core_throttling(interval=interval)413 diag_vals.extend(throt_vals)414 if throt_level > 0:415 diag_msgs.append(throt_msg)416 diag_level = max(diag_level, throt_level)417 # Check NetData system.idlejitter418 if self._check_idlejitter:419 jitter_vals, jitter_msg, jitter_level = self.check_idlejitter(interval=interval)420 diag_vals.extend(jitter_vals)421 if jitter_level > 0:422 diag_msgs.append(jitter_msg)423 diag_level = max(diag_level, jitter_level)424 # Check uptime425 up_vals, up_msg, up_level = self.check_uptime(interval=interval)426 diag_vals.extend(up_vals)427 if up_level > DiagnosticStatus.OK:428 diag_msgs.append(up_msg)429 diag_level = max(diag_level, up_level)430 # Check load431 load_vals, load_msg, load_level = self.check_load(interval=interval)432 diag_vals.extend(load_vals)433 if load_level > DiagnosticStatus.OK:434 diag_msgs.append(load_msg)435 diag_level = max(diag_level, load_level)436 if diag_msgs and diag_level > DiagnosticStatus.OK:437 usage_msg = ', '.join(set(diag_msgs))438 else:439 usage_msg = stat_dict[diag_level]440 self._usage_stat.values = diag_vals441 self._usage_stat.message = usage_msg442 self._usage_stat.level = diag_level443 def check_memory(self, event):444 diag_vals = []445 diag_msgs = []446 diag_level = DiagnosticStatus.OK447 # Check memory448 interval = math.ceil(self._memory_timer._period.to_sec())449 mem_vals, mem_msg, mem_level = self.check_free_memory(interval=interval)450 diag_vals.extend(mem_vals)451 if mem_level > DiagnosticStatus.OK:452 diag_msgs.append(mem_msg)453 diag_level = max(diag_level, mem_level)454 if diag_msgs and diag_level > DiagnosticStatus.OK:455 memory_msg = ', '.join(set(diag_msgs))456 else:457 memory_msg = stat_dict[diag_level]458 self._memory_stat.values = diag_vals459 self._memory_stat.message = memory_msg460 self._memory_stat.level = diag_level461 def publish_stats(self, event):462 msg = DiagnosticArray()463 msg.header.stamp = rospy.get_rostime()464 msg.status.append(self._info_stat)465 msg.status.append(self._usage_stat)466 msg.status.append(self._memory_stat)467 self._diag_pub.publish(msg)468if __name__ == '__main__':469 hostname = socket.gethostname()470 import optparse471 parser = optparse.OptionParser(usage="usage: cpu_monitor.py [--diag-hostname=cX]")472 parser.add_option("--diag-hostname", dest="diag_hostname",473 help="Computer name in diagnostics output (ex: 'c1')",474 metavar="DIAG_HOSTNAME",475 action="store", default = hostname)476 options, args = parser.parse_args(rospy.myargv())477 try:478 rospy.init_node('cpu_monitor_%s' % hostname)479 except rospy.exceptions.ROSInitException:480 print('CPU monitor is unable to initialize node. Master may not be running.')481 sys.exit(0)482 cpu_node = CPUMonitor(hostname, options.diag_hostname)...

Full Screen

Full Screen

showTestResult.py

Source:showTestResult.py Github

copy

Full Screen

1#!/usr/bin/python2"""3# Show logfile4"""5import sys6import os7import string8# import datetime9# import time10logdir = ''11def print_help():12 """ print help """13 print "possible option for this script"14 print "--------------------------------------------------"15 print "-h print this help screen"16 print "-L2=2 show last 2 checks from L2 file"17 print "-S=2 show last 2 checks from S file"18 print "-f=filename full_path_filename, L2 and S are ignored"19 print " "20 print " if no option is given the last check done is used"21 print "--------------------------------------------------"22 sys.exit(0)23args = dict()24for argument in sys.argv[1:]:25 if argument.startswith('-'):26 if '=' in argument:27 option, value = argument.strip()[1:].split('=')28 args[option.strip().upper()] = value.strip()29 else:30 args[argument.strip()[1:].upper()] = '-'31if 'H' in args:32 print_help()33 sys.exit(0)34run_path = r'/opt/stationtest'35if 'P' in args:36 run_path = args.get('P')37lib_path = run_path+r'/lib'38sys.path.insert(0, lib_path)39from general_lib import *40from lofar_lib import *41station_id = getHostName().upper()42def main():43 global logdir44 45 """ main function """46 fd = open(run_path+r'/checkHardware.conf', 'r')47 data = fd.readlines()48 fd.close()49 for line in data:50 if line.find('log-dir-local') != -1:51 key, logdir = line.strip().split('=')52 data_sets = []53 54 if 'F' in args:55 fullfilename = args.get('F')56 else:57 if 'L2' in args:58 testfilename = '%s_L2_StationTestHistory.csv' % station_id59 data_sets.append( ['L2', get_data(testfilename, int(args.get('L2', '1')))] )60 61 if 'S' in args: 62 testfilename = '%s_S_StationTestHistory.csv' % station_id63 data_sets.append( ['S', get_data(testfilename, int(args.get('S', '1')))] )64 65 if not 'L2' in args and not 'S' in args:66 testfilename = '%s_StationTest.csv' % station_id67 data_sets.append( ['', get_data(testfilename, 1)] )68 rcu_x = rcu_y = 069 _part = ''70 _part_nr = -171 # print data for all sets72 print "\n\n\n"73 for check_type, data in data_sets:74 message = "STATION-CHECK RESULTS %s for last %s checks" % (check_type, args.get('%s' % check_type, '1')) 75 banner_len = 10076 msg_len = len(message)77 print "-" * banner_len78 print ">" * ((banner_len - msg_len - 6) / 2) + " %s " % message + "<" * ((banner_len - msg_len - 6) / 2)79 print "-" * banner_len80 81 check_nr = int(args.get('%s' % check_type, '1')) - 182 for line in data:83 partnumber = -184 if line[0] == '#':85 continue86 d = line.strip().split(',')87 if len(d) < 4:88 continue89 date = d[0]90 if 'STATION' in line:91 if check_nr:92 message = "= csv -%s- (last - %d) =" % (check_type, check_nr)93 else:94 message = "= csv -%s- (last) =" % check_type95 print ' ' + '=' * len(message) 96 print ' ' + message97 print ' ' + '=' * len(message) 98 check_nr -= 199 part = d[1]100 if d[2] != '---':101 partnumber = int(d[2])102 if part == 'LBL':103 if partnumber < 48:104 print "ERROR: LBL %d NOT a legal partnumber" % partnumber105 rcu_x = 0106 rcu_y = 0107 else:108 rcu_x = (partnumber - 48) * 2109 rcu_y = (partnumber - 48) * 2 + 1110 if part in ('LBH', 'HBA'):111 rcu_x = partnumber * 2112 rcu_y = partnumber * 2 + 1113 msg = d[3].strip()114 msg_info = string.join(d[4:], " ")115 keyvalue = dict()116 for i in range(4, len(d)):117 if d[i].find('=') != -1:118 key, valstr = d[i].split('=')119 vallist = valstr.split(' ')120 if len(vallist) == 1:121 keyvalue[key] = vallist[0]122 elif len(vallist) > 1:123 keyvalue[key] = vallist124 else:125 keyvalue[d[i]] = '-'126 if part == 'NFO':127 print_info(msg, keyvalue, msg_info)128 if part == 'SPU':129 if part != _part:130 _part = part131 hdr = "\n== SPU "132 print hdr + "=" * (banner_len - len(hdr))133 print_spu(partnumber, msg, keyvalue, msg_info)134 if part == 'RSP':135 if part != _part:136 _part = part137 hdr = "\n== RSP "138 print hdr + "=" * (banner_len - len(hdr))139 print_rsp(partnumber, msg, keyvalue)140 if part == 'TBB':141 if part != _part:142 _part = part143 hdr = "\n== TBB "144 print hdr + "="*(banner_len - len(hdr))145 print_tbb(partnumber, msg, keyvalue)146 if part == 'RCU':147 if part != _part:148 _part = part149 hdr = "\n== RCU "150 print hdr + "=" * (banner_len - len(hdr))151 print_rcu(partnumber, msg, keyvalue)152 if part in ('LBL', 'LBH'):153 if part != _part:154 _part = part155 if part == 'LBL':156 hdr = "\n== LBA Low "157 else:158 hdr = "\n== LBA High "159 print hdr + "=" * (banner_len - len(hdr))160 print_lba(partnumber, msg, keyvalue, rcu_x, rcu_y)161 if part == 'HBA':162 if part != _part:163 _part = part164 hdr = "\n== HBA "165 print hdr + "=" * (banner_len - len(hdr))166 if partnumber != -1 and partnumber != _part_nr:167 _part_nr = partnumber168 header = "Tile %d (RCU %d/%d)" % (partnumber, rcu_x, rcu_y)169 print "\n-- %s %s" % (header, '-' * (banner_len - len(header)))170 print_hba(partnumber, msg, keyvalue, rcu_x, rcu_y)171 #print '\n' + '#' * banner_len172def get_data(filename, n_checks):173 if not filename.startswith('/'):174 if os.path.exists(logdir):175 fullfilename = os.path.join(logdir, filename)176 else:177 print "not a valid log dir"178 sys.exit(-1)179 try:180 fd = open(fullfilename, 'r')181 data = fd.readlines()182 fd.close()183 except:184 print "%s not found in %s" % (filename, logdir)185 sys.exit(-1)186 187 first_line = 0188 check_cnt = 0189 for i in range(len(data) - 1, -1, -1):190 line = data[i]191 if line[0] == '#':192 continue193 if 'STATION' in line:194 first_line = i195 check_cnt += 1196 if check_cnt == n_checks:197 break198 return data[first_line:]199def print_info(msg, keyvalue, msg_info):200 """201 print NFO line202 """203 if msg == 'VERSIONS':204 print "Used script versions: checkHardware=%s, test_db=%s, test_lib=%s, search_lib=%s\n" % (205 keyvalue.get('CHECK'), keyvalue.get('DB'), keyvalue.get('TEST'), keyvalue.get('SEARCH'))206 if msg == 'STATION':207 print "-- Station name : %s" % keyvalue.get('NAME')208 if msg == 'RUNTIME':209 print "-- Check runtime : %s .. %s" % (210 keyvalue.get('START').replace('T', ' '), keyvalue.get('STOP'). replace('T', ' '))211 if msg == 'DRIVER':212 if 'RSPDRIVER' in keyvalue:213 print "-- RSPDriver : DOWN"214 if 'TBBDRIVER' in keyvalue:215 print "-- TBBDriver : DOWN"216 if msg == 'BOARD':217 boardstr = ""218 for i in range(24):219 if 'RSP-%d' % i in keyvalue:220 boardstr += "%d, " % i221 print "-- RSP board DOWN : %s" % boardstr[:-2]222 if msg == 'CHECKS':223 """E5"""224 checks = msg_info.split()225 info = []226 if 'RV' in checks:227 info.append('RSP-version')228 if 'TV' in checks:229 info.append('TBB-version') 230 if 'TM' in checks:231 info.append('TBB-memory')232 if 'SPU' in checks:233 info.append('SPU-check') 234 if 'RBV' in checks:235 info.append('RSP-voltage') 236 if len(info): 237 print "-- Checks done : %s" % string.join(info, ', ')238 info = []239 for mode in '1234567':240 if 'M%s' % mode in checks:241 info.append('Modem')242 if 'SH%s' % mode in checks:243 info.append('Short')244 if 'F%s' % mode in checks:245 info.append('Flat')246 if 'D%s' % mode in checks:247 info.append('Down')248 if 'S%s' % mode in checks:249 info.append('RF') 250 if 'O%s' % mode in checks:251 info.append('Oscillation') 252 if 'SP%s' % mode in checks:253 info.append('Spurious')254 if 'SN%s' % mode in checks:255 info.append('Summator-noise')256 for check in checks:257 if 'NS%s' % mode in check.split('='):258 info.append('Noise[%ssec]' % check.split('=')[1])259 if 'E%s' % mode in checks:260 info.append('Elements') 261 if len(info): 262 print "-- Checks done M%s : %s" % (mode, string.join(info, ', '))263 info = []264 if msg == 'STATISTICS':265 print "-- Bad antennas :",266 if keyvalue.get('BAD_LBL') != '-1':267 print "LBL=%s " % keyvalue.get('BAD_LBL'),268 if keyvalue.get('BAD_LBH') != '-1':269 print "LBH=%s " % keyvalue.get('BAD_LBH'),270 if keyvalue.get('BAD_HBA') != '-1':271 print "HBA=%s " % keyvalue.get('BAD_HBA'),272 if keyvalue.get('BAD_HBA0') != '-1':273 print "HBA0=%s " % keyvalue.get('BAD_HBA0'),274 if keyvalue.get('BAD_HBA1') != '-1':275 print "HBA1=%s " % keyvalue.get('BAD_HBA1'),276 print277 if msg == 'BADLIST':278 # 20150723,NFO,---,BADLIST,LBL=83 84 94 95279 bad_ant_str = msg_info.replace('=', '(').replace(' ', ',').replace(';', ') ') + ')'280 print "-- bad-antenna-list : %s" % bad_ant_str281 return282def print_spu(partnumber, msg, keyvalue, msg_info):283 """284 print SPU line285 """286 if msg == 'VOLTAGE':287 print " Subrack %1d wrong voltage: %s" % (partnumber, msg_info)288 if msg == 'TEMPERATURE':289 print " Subrack %1d high temperature: PCB=%s" % (290 partnumber, keyvalue.get('PCB'))291 return292def print_rsp(partnumber, msg, keyvalue):293 """294 print RSP line295 """296 if msg == 'VERSION':297 if 'RSPDRIVER' in keyvalue:298 print " Wrong RSPDriver version, %s" % keyvalue.get('RSPDRIVER')299 if 'RSPCTL' in keyvalue:300 print " Wrong rspctl version, %s" % keyvalue.get('RSPCTL')301 if 'AP' in keyvalue or 'BP' in keyvalue:302 print " Board %2d wrong firmware version: AP=%s BP=%s" % (303 partnumber, keyvalue.get('AP'), keyvalue.get('BP'))304 if msg == 'VOLTAGE':305 print " Board %2d wrong voltage: 1.2V=%s 2.5V=%s 3.3V=%s" % (306 partnumber, keyvalue.get('1.2V'), keyvalue.get('2.5V'), keyvalue.get('3.3V'))307 if msg == 'TEMPERATURE':308 print " Board %2d high temperature: PCB=%s BP=%s AP0=%s AP1=%s AP2=%s AP3=%s" % (309 partnumber, keyvalue.get('PCB'), keyvalue.get('BP'), keyvalue.get('AP0'), keyvalue.get('AP1'),310 keyvalue.get('AP2'), keyvalue.get('AP3'))311 return312def print_tbb(partnumber, msg, keyvalue):313 """314 print TBB line315 """316 if msg == 'VERSION':317 if 'TBBDRIVER' in keyvalue:318 print " Wrong TBBDriver version, %s" % keyvalue.get('TBBDRIVER')319 if 'TBBCTL' in keyvalue:320 print " Wrong tbbctl version, %s" % keyvalue.get('TBBCTL')321 if 'TP' in keyvalue or 'MP' in keyvalue:322 print " Board %2d wrong firmware version: TP=%s MP=%s" % (323 partnumber, keyvalue.get('TP'), keyvalue.get('MP'))324 if msg == 'MEMORY':325 print " Board %2d Memory address or dataline error" % partnumber326 return327def print_rcu(partnumber, msg, keyvalue):328 """329 print RCU line330 """331 if msg == 'BROKEN':332 print " RCU %d Broken" % partnumber333 return334def print_lba(partnumber, msg, keyvalue, rcu_x, rcu_y):335 """336 print LBA line337 """338 lba_number = partnumber339 if msg == 'NOSIGNAL':340 print " NO test signal found"341 if msg == 'TESTSIGNAL':342 print343 print " X test done with subband=%s and ref.signal=%sdB" % (344 keyvalue.get('SUBBANDX'), keyvalue.get('SIGNALX'))345 print " Y test done with subband=%s and ref.signal=%sdB" % (346 keyvalue.get('SUBBANDY'), keyvalue.get('SIGNALY'))347 if msg == 'TOOLOW':348 print " Average signal strenght Too Low AVG %sdB" % keyvalue.get('AVG')349 if msg == 'DOWN':350 print " Antenna %2d, %-11s, Down: X=%sdB Xoffset=%s Y=%sdB Yoffset=%s" % (351 lba_number, 'RCU %d/%d' % (rcu_x, rcu_y),352 keyvalue.get('X', ('?',)), keyvalue.get('Xoff', ('?',)),353 keyvalue.get('Y', ('?',)), keyvalue.get('Yoff', ('?',)))354 if msg == 'SHORT':355 if 'Xmean' in keyvalue:356 print " Antenna %2d, %-7s, X Short: value=%s" % (357 lba_number, 'RCU %d' % rcu_x, keyvalue.get('Xmean'))358 if 'Ymean' in keyvalue:359 print " Antenna %2d, %-7s, Y Short: value=%s" % (360 lba_number, 'RCU %d' % rcu_y, keyvalue.get('Ymean'))361 if msg == 'FLAT':362 if 'Xmean' in keyvalue:363 print " Antenna %2d, %-7s, X Flat: value=%s" % (364 lba_number, 'RCU %d' % rcu_x, keyvalue.get('Xmean'))365 if 'Ymean' in keyvalue:366 print " Antenna %2d, %-7s, Y Flat: value=%s" % (367 lba_number, 'RCU %d' % rcu_y, keyvalue.get('Ymean'))368 if msg == 'OSCILLATION':369 if 'X' in keyvalue or 'Xbands' in keyvalue:370 print " Antenna %2d, %-7s, X Oscillation" % (lba_number, 'RCU %d' % rcu_x)371 if 'Y' in keyvalue or 'Ybands' in keyvalue:372 print " Antenna %2d, %-7s, Y Oscillation" % (lba_number, 'RCU %d' % rcu_y)373 if msg == 'LOW_NOISE':374 if 'Xproc' in keyvalue:375 print " Antenna %2d, %-7s, X Low Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (376 lba_number, 'RCU %d' % rcu_x, keyvalue.get('Xproc'), keyvalue.get('Xval'),377 keyvalue.get('Xdiff', '-'), keyvalue.get('Xref'))378 if 'Yproc' in keyvalue:379 print " Antenna %2d, %-7s, Y Low Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (380 lba_number, 'RCU %d' % rcu_y, keyvalue.get('Yproc'), keyvalue.get('Yval'),381 keyvalue.get('Ydiff', '-'), keyvalue.get('Yref'))382 if msg == 'HIGH_NOISE':383 if 'Xproc' in keyvalue:384 print " Antenna %2d, %-7s, X High Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (385 lba_number, 'RCU %d' % rcu_x, keyvalue.get('Xproc'), keyvalue.get('Xval'),386 keyvalue.get('Xdiff', '-'), keyvalue.get('Xref'))387 if 'Yproc' in keyvalue:388 print " Antenna %2d, %-7s, Y High Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (389 lba_number, 'RCU %d' % rcu_y, keyvalue.get('Yproc'), keyvalue.get('Yval'),390 keyvalue.get('Ydiff', '-'), keyvalue.get('Yref'))391 if msg == 'JITTER':392 if 'Xdiff' in keyvalue:393 print " Antenna %2d, %-7s, X Jitter: %s%% bad, fluctuation=%sdB, normal=%sdB" % (394 lba_number, 'RCU %d' % rcu_x, keyvalue.get('Xproc', '-'),395 keyvalue.get('Xdiff'), keyvalue.get('Xref'))396 if 'Ydiff' in keyvalue:397 print " Antenna %2d, %-7s, Y Jitter: %s%% bad, fluctuation=%sdB, normal=%sdB" % (398 lba_number, 'RCU %d' % rcu_y, keyvalue.get('Yproc', '-'),399 keyvalue.get('Ydiff'), keyvalue.get('Yref'))400 if msg == 'SPURIOUS':401 if 'X' in keyvalue:402 print " Antenna %2d, %-7s, X Spurious signals" % (lba_number, 'RCU %d' % rcu_x)403 if 'Y' in keyvalue:404 print " Antenna %2d, %-7s, Y Spurious signals" % (lba_number, 'RCU %d' % rcu_y)405 if msg == 'FAIL' or msg == 'RF_FAIL':406 if 'X' in keyvalue:407 print " Antenna %2d, %-7s, X RF fail: signal=%sdB" % (408 lba_number, 'RCU %d' % rcu_x, keyvalue.get('X'))409 if 'Y' in keyvalue:410 print " Antenna %2d, %-7s, Y RF fail: signal=%sdB" % (411 lba_number, 'RCU %d' % rcu_y, keyvalue.get('Y'))412def print_hba(partnumber, msg, keyvalue, rcu_x, rcu_y):413 """414 print HBA line415 """416 _c_summator_defect = 0417 if msg == 'NOSIGNAL':418 print " NO test signal found"419 if msg == 'MODEM':420 for i in range(1, 17, 1):421 key = "E%02d" % i422 if key in keyvalue:423 print " E%02d modem fault (%s)" % (i, keyvalue[key])424 if msg == 'OSCILLATION':425 if 'X' in keyvalue or 'Xbands' in keyvalue:426 print " X Oscillation"427 if 'Y' in keyvalue or 'Ybands' in keyvalue:428 print " Y Oscillation"429 if msg == 'C_SUMMATOR':430 _c_summator_defect = 1431 print " Modem errors (all elements)"432 if msg == 'P_SUMMATOR':433 print " No RF all elements"434 if msg == 'SUMMATOR_NOISE':435 if 'X' in keyvalue:436 print " X Summator noise"437 if 'Y' in keyvalue:438 print " Y Summator noise"439 if msg == 'SPURIOUS':440 if 'X' in keyvalue:441 print " X Spurious signals"442 if 'Y' in keyvalue:443 print " Y Spurious signals"444 if msg == 'LOW_NOISE':445 if 'Xproc' in keyvalue:446 print " X Low Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (447 keyvalue.get('Xproc'), keyvalue.get('Xval'), keyvalue.get('Xdiff', '-'), keyvalue.get('Xref'))448 if 'Yproc' in keyvalue:449 print " Y Low Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (450 keyvalue.get('Yproc'), keyvalue.get('Yval'), keyvalue.get('Ydiff', '-'), keyvalue.get('Yref'))451 if msg == 'HIGH_NOISE':452 if 'Xproc' in keyvalue:453 print " X High Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (454 keyvalue.get('Xproc'), keyvalue.get('Xval'), keyvalue.get('Xdiff', '-'), keyvalue.get('Xref'))455 if 'Yproc' in keyvalue:456 print " Y High Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (457 keyvalue.get('Yproc'), keyvalue.get('Yval'), keyvalue.get('Ydiff', '-'), keyvalue.get('Yref'))458 if msg == 'JITTER':459 if 'Xdiff' in keyvalue:460 print " X Jitter: %s%% bad, fluctuation=%sdB, normal=%sdB" % (461 keyvalue.get('Xproc'), keyvalue.get('Xdiff'), keyvalue.get('Xref'))462 if 'Ydiff' in keyvalue:463 print " Y Jitter: %s%% bad, fluctuation=%sdB, normal=%sdB" % (464 keyvalue.get('Yproc'), keyvalue.get('Ydiff'), keyvalue.get('Yref'))465 if msg == 'RF_FAIL' or msg == 'RF_TILE_FAIL':466 if 'X' in keyvalue:467 signal_128, sb_128, ref_128, signal_253, sb_253, ref_253 = keyvalue.get('X')468 print " X RF Fail: ",469 print "no-delay(test=%5.1fdB ref=%5.1fdB sb=%d) " % (470 float(signal_128), float(ref_128), int(sb_128)),471 print "full-delay(test=%5.1fdB ref=%5.1fdB sb=%d)" % (472 float(signal_253), float(ref_253), int(sb_253))473 if 'Y' in keyvalue:474 signal_128, sb_128, ref_128, signal_253, sb_253, ref_253 = keyvalue.get('Y')475 print " Y RF Fail: ",476 print "no-delay(test=%5.1fdB ref=%5.1fdB sb=%d) " % (477 float(signal_128), float(ref_128), int(sb_128)),478 print "full-delay(test=%5.1fdB ref=%5.1fdB sb=%d)" % (479 float(signal_253), float(ref_253), int(sb_253))480 if msg == 'E_FAIL':481 # loop over number of elements482 for i in range(1, 17, 1):483 if _c_summator_defect:484 continue485 if 'M%d' % i in keyvalue or 'X%d' % i in keyvalue or 'Y%d' % i in keyvalue \486 or 'OX%d' % i in keyvalue or 'OY%d' % i in keyvalue \487 or 'SPX%d' % i in keyvalue or 'SPY%d' % i in keyvalue \488 or 'LNX%d' % i in keyvalue or 'HNX%d' % i in keyvalue or 'JX%d' % i in keyvalue \489 or 'LNY%d' % i in keyvalue or 'HNY%d' % i in keyvalue or 'JY%d' % i in keyvalue:490 print " Element %d" % i491 if 'M%d' % i in keyvalue:492 info = keyvalue.get('M%d' % i)493 if info == 'error':494 print " Modem error"495 if info == '??':496 print " No modem communication"497 else:498 if 'OX%d' % i in keyvalue:499 print " X Oscillating"500 if 'OY%d' % i in keyvalue:501 print " Y Oscillating"502 if 'SPX%d' % i in keyvalue:503 print " X Spurious"504 if 'SPY%d' % i in keyvalue:505 print " Y Spurious"506 if 'LNX%d' % i in keyvalue:507 print " X Low Noise, signal=%sdB fluctuation=%sdB" % (508 keyvalue.get('LNX%d' % i)[0], keyvalue.get('LNX%d' % i)[1])509 if 'HNX%d' % i in keyvalue:510 print " X High Noise, signal=%sdB fluctuation=%sdB" % (511 keyvalue.get('HNX%d' % i)[0], keyvalue.get('HNX%d' % i)[1])512 if 'JX%d' % i in keyvalue:513 print " X Jitter, fluctuation=%sdB" % keyvalue.get('JX%d' % i)514 if 'LNY%d' % i in keyvalue:515 print " Y Low Noise, signal=%sdB fluctuation=%sdB" % (516 keyvalue.get('LNY%d' % i)[0], keyvalue.get('LNY%d' % i)[1])517 if 'HNY%d' % i in keyvalue:518 print " Y High Noise, signal=%sdB fluctuation=%sdB" % (519 keyvalue.get('HNY%d' % i)[0], keyvalue.get('HNY%d' % i)[1])520 if 'JY%d' % i in keyvalue:521 print " Y Jitter, fluctuation=%sdB" % keyvalue.get('JY%d' % i)522 if 'X%d' % i in keyvalue:523 signal_128, sb_128, ref_128, signal_253, sb_253, ref_253 = keyvalue.get('X%d' % i)524 print " X RF Fail: ",525 print "no-delay(test=%5.1fdB ref=%5.1fdB sb=%d) " % (526 float(signal_128), float(ref_128), int(sb_128)),527 print "full-delay(test=%5.1fdB ref=%5.1fdB sb=%d)" % (528 float(signal_253), float(ref_253), int(sb_253))529 if 'Y%d' % i in keyvalue:530 signal_128, sb_128, ref_128, signal_253, sb_253, ref_253 = keyvalue.get('Y%d' % i)531 print " Y RF Fail: ",532 print "no-delay(test=%5.1fdB ref=%5.1fdB sb=%d) " % (533 float(signal_128), float(ref_128), int(sb_128)),534 print "full-delay(test=%5.1fdB ref=%5.1fdB sb=%d)" % (535 float(signal_253), float(ref_253), int(sb_253))536if __name__ == '__main__':...

Full Screen

Full Screen

common.js

Source:common.js Github

copy

Full Screen

1function showTip(info){2 $('tips').innerHTML = info;3}4function sendForm(formId,action,response,target,effect){5 // Ajax方式提交表单6 if (CheckForm($(formId),'ThinkAjaxResult'))//表单数据验证7 {8 ThinkAjax.sendForm(formId,action,response,target);9 }10 //Form.reset(formId);11}12rowIndex = 0;13function prepareIE(height, overflow){14 bod = document.getElementsByTagName('body')[0];15 bod.style.height = height;16 //bod.style.overflow = overflow;17 htm = document.getElementsByTagName('html')[0];18 htm.style.height = height;19 //htm.style.overflow = overflow; 20}21function hideSelects(visibility){22 selects = document.getElementsByTagName('select');23 for(i = 0; i < selects.length; i++) {24 selects[i].style.visibility = visibility;25 }26}27document.write('<div id="overlay" class="none"></div><div id="lightbox" class="none"></div>');28// 显示light窗口29function showPopWin(content,width,height){30 // IE 31 prepareIE('100%', 'hidden');32 window.scrollTo(0, 0); 33 hideSelects('hidden');//隐藏所有的<select>标记34 $('overlay').style.display = 'block';35 var arrayPageSize = getPageSize();36 var arrayPageScroll = getPageScroll();37 $('lightbox').style.display = 'block';38 $('lightbox').style.top = (arrayPageScroll[1] + ((arrayPageSize[3] - 35 - height) / 2) + 'px');39 $('lightbox').style.left = (((arrayPageSize[0] - 25 - width) / 2) + 'px');40 $('lightbox').innerHTML = content;41}42function fleshVerify(){43//重载验证码44var timenow = new Date().getTime();45$('verifyImg').src= APP+'/Public/verify/'+timenow;46}47function setseokey(){48 var sk = $('#seokey_list').val();49 if(sk){50 UE_content.focus();51 UE_content.execCommand("insertHTML",sk.join(','));52 }53}54function get_url_by_title(){55 if($(".titletxt") && $(".urltxt")){56 var title = $(".titletxt").val();57 $.ajax({58 type:"POST",59 url:'/index.php/Admin/Public/urlbytitle?isajax=1',60 data:'title='+title,61 success:function(data){62 if(data.status==1){63 $(".urltxt").val(data.info);64 }65 }66 })67 }68}69function allSelect(){70 var colInputs = document.getElementsByTagName("input");71 for (var i=0; i < colInputs.length; i++)72 {73 colInputs[i].checked= true;74 }75}76function allUnSelect(){77 var colInputs = document.getElementsByTagName("input");78 for (var i=0; i < colInputs.length; i++)79 {80 colInputs[i].checked= false;81 }82}83function InverSelect(){84 var colInputs = document.getElementsByTagName("input");85 for (var i=0; i < colInputs.length; i++)86 {87 colInputs[i].checked= !colInputs[i].checked;88 }89}90function WriteTo(id){91 var type = $F('outputType');92 switch (type)93 {94 case 'EXCEL':WriteToExcel(id);break;95 case 'WORD':WriteToWord(id);break;96 97 }98 return ;99}100function build(id){101 window.location = APP+'/Card/batch/type/'+id;102}103function shortcut(){104 var name = window.prompt("输入该快捷方式的显示名称","");105 if (name !=null)106 {107 var url = location.href;108 ThinkAjax.send(location.protocol+'//'+location.hostname+APP+'/Shortcut/ajaxInsert/','ajax=1&name='+name+'&url='+url);109 }110}111function show(){112 if (document.getElementById('menu').style.display!='none')113 {114 document.getElementById('menu').style.display='none';115 document.getElementById('main').className = 'full';116 }else {117 document.getElementById('menu').style.display='inline';118 document.getElementById('main').className = 'main';119 }120}121function CheckAll(strSection)122 {123 var i;124 var colInputs = document.getElementById(strSection).getElementsByTagName("input");125 for (i=1; i < colInputs.length; i++)126 {127 colInputs[i].checked=colInputs[0].checked;128 }129 }130function add(id){131 if (id)132 {133 location.href = URL+"/add/action_name/"+ACTION_NAME+"/id/"+id;134 }else{135 location.href = URL+"/add/action_name/"+ACTION_NAME+"";136 }137}138function news(wd){139 if (wd)140 {141 location.href = APP+"/Admin/New/add/action_name/"+ACTION_NAME+"/wd/"+wd;142 }else{143 location.href = URL+"/Admin/New/add/action_name/"+ACTION_NAME+"";144 }145}146function showHideSearch(){147 if (document.getElementById('searchM').style.display=='inline')148 {149 document.getElementById('searchM').style.display='none';150 document.getElementById('showText').value ='高级';151 document.getElementById('key').style.display='inline';152 }else {153 document.getElementById('searchM').style.display='inline';154 document.getElementById('showText').value ='隐藏';155 document.getElementById('key').style.display='none';156 }157}158function top(id){159 var keyValue;160 if (id)161 {162 keyValue = id;163 }else {164 keyValue = getSelectCheckboxValues();165 }166 if (!keyValue)167 {168 alert('请选择置顶项!');169 return false;170 }171 location.href = URL+"/top/action_name/"+ACTION_NAME+"/id/"+keyValue;172}173function sort(id){174 var keyValue;175 keyValue = getSelectCheckboxValues();176 location.href = URL+"/sort/action_name/"+ACTION_NAME+"/sortId/"+keyValue;177}178function high(id){179 var keyValue;180 if (id)181 {182 keyValue = id;183 }else {184 keyValue = getSelectCheckboxValues();185 }186 if (!keyValue)187 {188 alert('请选择高亮项!');189 return false;190 }191 location.href = URL+"/high/action_name/"+ACTION_NAME+"/id/"+keyValue;192}193function recommend(id){194 var keyValue;195 if (id)196 {197 keyValue = id;198 }else {199 keyValue = getSelectCheckboxValues();200 }201 if (!keyValue)202 {203 alert('请选择推荐项!');204 return false;205 }206 location.href = URL+"/recommend/action_name/"+ACTION_NAME+"/id/"+keyValue;207}208function unrecommend(id){209 var keyValue;210 if (id)211 {212 keyValue = id;213 }else {214 keyValue = getSelectCheckboxValues();215 }216 if (!keyValue)217 {218 alert('请选择项目!');219 return false;220 }221 location.href = URL+"/unrecommend/action_name/"+ACTION_NAME+"/id/"+keyValue;222}223function pass(id){224 var keyValue;225 if (id)226 {227 keyValue = id;228 }else {229 keyValue = getSelectCheckboxValues();230 }231 if (!keyValue)232 {233 alert('请选择审核项!');234 return false;235 }236 if (window.confirm('确实审核通过吗?'))237 {238 window.location.href = URL+ '/checkPass/action_name/'+ACTION_NAME+'/id/'+keyValue;239 //ThinkAjax.send(URL+"/checkPass/","id="+keyValue+'&ajax=1');240 }241}242function sortBy (field,sort){243 location.href = "?_order="+field+"&_sort="+sort;244}245function cache(){246 ThinkAjax.send(URL+'/cache/action_name/'+ACTION_NAME,'ajax=1');247}248function forbid(id){249 location.href = URL+"/forbid/action_name/"+ACTION_NAME+"/id/"+id;250}251function recycle(id){252 var keyValue;253 if (id)254 {255 keyValue = id;256 }else {257 keyValue = getSelectCheckboxValue();258 }259 if (!keyValue)260 {261 alert('请选择要还原的项目!');262 return false;263 }264 location.href = URL+"/recycle/action_name/"+ACTION_NAME+"/id/"+keyValue;265}266function resume(id){267 location.href = URL+"/resume/action_name/"+ACTION_NAME+"/id/"+id;268}269function output(){270 location.href = URL+"/output/action_name/"+ACTION_NAME+"/";271}272function member(id){273 location.href = URL+"/../Member/edit/action_name/"+ACTION_NAME+"/id/"+id;274}275function chat(id){276 location.href = URL+"/../Chat/index/action_name/"+ACTION_NAME+"/girlId/"+id;277}278function login(id){279 location.href = URL+"/../Login/index/action_name/"+ACTION_NAME+"/type/4/id/"+id;280}281function child(id){282 location.href = URL+"/index/action_name/"+ACTION_NAME+"/pid/"+id;283}284function action(id){285 location.href = URL+"/action/action_name/"+ACTION_NAME+"/groupId/"+id;286}287function access(id){288 location.href= URL+"/access/action_name/"+ACTION_NAME+"/id/"+id;289}290function app(id){291 location.href = URL+"/app/action_name/"+ACTION_NAME+"/groupId/"+id;292}293function module(id){294 location.href = URL+"/module/action_name/"+ACTION_NAME+"/groupId/"+id;295}296function user(id){297 location.href = URL+"/user/action_name/"+ACTION_NAME+"/id/"+id;298}299 //+---------------------------------------------------300 //| 打开模式窗口,返回新窗口的操作值301 //+---------------------------------------------------302 function PopModalWindow(url,width,height)303 {304 var result=window.showModalDialog(url,"win","dialogWidth:"+width+"px;dialogHeight:"+height+"px;center:yes;status:no;scroll:no;dialogHide:no;resizable:no;help:no;edge:sunken;");305 return result;306 }307 308function viewstyle(id){309 var keyValue;310 if (id)311 {312 keyValue = id;313 }else {314 keyValue = getSelectCheckboxValue();315 }316 location.href = URL+"/style/action_name/"+ACTION_NAME+"/tplid/"+keyValue;317} 318function read(id){319 var keyValue;320 if (id)321 {322 keyValue = id;323 }else {324 keyValue = getSelectCheckboxValue();325 }326 if (!keyValue)327 {328 alert('请选择编辑项!');329 return false;330 }331 location.href = URL+"/read/action_name/"+ACTION_NAME+"/id/"+keyValue;332}333function edit(id){334 var keyValue;335 if (id)336 {337 keyValue = id;338 }else {339 keyValue = getSelectCheckboxValue();340 }341 if (!keyValue)342 {343 alert('请选择编辑项!');344 return false;345 }346 location.href = URL+"/edit/action_name/"+ACTION_NAME+"/id/"+keyValue;347}348var selectRowIndex = Array();349function del(id){350 var keyValue;351 if (id)352 {353 keyValue = id;354 }else {355 keyValue = getSelectCheckboxValues();356 }357 if (!keyValue)358 {359 alert('请选择删除项!');360 return false;361 }362 if (window.confirm('确实要删除选择项吗?'))363 {364 location.href = URL+"/delete/action_name/"+ACTION_NAME+"/id/"+keyValue;365 }366}367function foreverdel(id){368 var keyValue;369 if (id)370 {371 keyValue = id;372 }else {373 keyValue = getSelectCheckboxValues();374 }375 if (!keyValue)376 {377 alert('请选择删除项!');378 return false;379 }380 if (window.confirm('确实要永久删除选择项吗?'))381 {382 ThinkAjax.send(URL+"/foreverdelete/action_name/"+ACTION_NAME+"/","id="+keyValue+'&ajax=1',doDelete);383 }384}385function getTableRowIndex(obj){ 386 selectRowIndex[0] =obj.parentElement.parentElement.rowIndex;/*当前行对象*/387}388function doDelete(data,status){389 if (status==1)390 {391 var Table = $('checkList');392 var len = selectRowIndex.length;393 for (var i=len-1;i>=0;i-- )394 {395 //删除表格行396 Table.deleteRow(selectRowIndex[i]);397 }398 selectRowIndex = Array();399 }400}401 function delAttach(id,showId){402 var keyValue;403 if (id)404 {405 keyValue = id;406 }else {407 keyValue = getSelectCheckboxValues();408 }409 if (!keyValue)410 {411 alert('请选择删除项!');412 return false;413 }414 if (window.confirm('确实要删除选择项吗?'))415 {416 $('result').style.display = 'block';417 ThinkAjax.send(URL+"/delAttach/action_name/"+ACTION_NAME+"/","id="+keyValue+'&_AJAX_SUBMIT_=1');418 if (showId != undefined)419 {420 $(showId).innerHTML = '';421 }422 }423}424function clearData(){425 if (window.confirm('确实要清空全部数据吗?'))426 {427 location.href = URL+"/clear/action_name/"+ACTION_NAME+"/";428 }429}430function takeback(id){431 var keyValue;432 if (id)433 {434 keyValue = id;435 }else {436 keyValue = getSelectCheckboxValues();437 }438 if (!keyValue)439 {440 alert('请选择回收项!');441 return false;442 }443 if (window.confirm('确实要回收选择项吗?'))444 {445 location.href = URL+"/takeback/action_name/"+ACTION_NAME+"/id/"+keyValue;446 }447}448function getSelectCheckboxValue(){449 var obj = document.getElementsByName('key');450 var result ='';451 for (var i=0;i<obj.length;i++)452 {453 if (obj[i].checked==true)454 return obj[i].value;455 }456 return false;457}458function getSelectCheckboxValues(){459 var obj = document.getElementsByName('key');460 var result ='';461 var j= 0;462 for (var i=0;i<obj.length;i++)463 {464 if (obj[i].checked==true){465 selectRowIndex[j] = i+1;466 result += obj[i].value+",";467 j++;468 }469 }470 return result.substring(0, result.length-1);471}472 function change(e) 473 { 474 if (!document.all)475 {return ;476 }477 var e = e || event;478 var oObj = e.srcElement || e.target; 479 //if(oObj.tagName.toLowerCase() == "td") 480 // { 481 /*482 var oTable = oObj.parentNode.parentNode; 483 for(var i=1; i<oTable.rows.length; i++) 484 { 485 oTable.rows[i].className = "out"; 486 oTable.rows[i].tag = false; 487 } */488 var obj= document.getElementById('checkList').getElementsByTagName("input");489 var oTr = oObj.parentNode; 490 var row = oObj.parentElement.rowIndex-1;491 if(obj[row]!=undefined){492 if (oTr.className == 'down')493 {494 oTr.className = 'out'; 495 obj[row].checked = false;496 oTr.tag = true; 497 }else {498 oTr.className = 'down'; 499 obj[row].checked = true;500 oTr.tag = true; 501 }502 }503 //} 504 } 505 506 function out(e) 507 { 508 var e = e || event;509 var oObj = e.srcElement || e.target; 510 511 var oTr = oObj.parentNode; 512 if(!oTr.tag) 513 oTr.className = "out"; 514 515 } 516 517 function over(e) 518 { 519 var e = e || event;520 var oObj = e.srcElement || e.target; 521 522 var oTr = oObj.parentNode; 523 if(!oTr.tag) 524 oTr.className = "over"; 525 526 } 527function check_Sel_Multi(id1, id2){ 528 if(jQuery("#sel_multi").children('option').size()>0){529 var ids = ','+jQuery("#sel_multi").val()+','+jQuery("#catid").val()+',';530 jQuery("#catstr").val(ids);531 }532} 533//---------------------------------------------------------------------534// 多选改进方法 by Liu21st at 2005-11-29535// 536//537//-------------------------begin---------------------------------------538function searchItem(item){539 for(i=0;i<selectSource.length;i++)540 if (selectSource[i].text.indexOf(item)!=-1)541 {selectSource[i].selected = true;break;}542}543function addItem(){544 for(i=0;i<selectSource.length;i++)545 if(selectSource[i].selected){546 selectTarget.add( new Option(selectSource[i].text,selectSource[i].value));547 }548 for(i=0;i<selectTarget.length;i++)549 for(j=0;j<selectSource.length;j++)550 if(selectSource[j].text==selectTarget[i].text)551 selectSource[j]=null;552}553function delItem(){554 for(i=0;i<selectTarget.length;i++)555 if(selectTarget[i].selected){556 selectSource.add(new Option(selectTarget[i].text,selectTarget[i].value));557 558 }559 for(i=0;i<selectSource.length;i++)560 for(j=0;j<selectTarget.length;j++)561 if(selectTarget[j].text==selectSource[i].text) selectTarget[j]=null;562}563function delAllItem(){564 for(i=0;i<selectTarget.length;i++){565 selectSource.add(new Option(selectTarget[i].text,selectTarget[i].value));566 567 }568 selectTarget.length=0;569}570function addAllItem(){571 for(i=0;i<selectSource.length;i++){572 selectTarget.add(new Option(selectSource[i].text,selectSource[i].value));573 574 }575 selectSource.length=0;576}577function getReturnValue(){578 for(i=0;i<selectTarget.length;i++){579 selectTarget[i].selected = true;580 }581}582function loadBar(fl)583//fl is show/hide flag584{585 var x,y;586 if (self.innerHeight)587 {// all except Explorer588 x = self.innerWidth;589 y = self.innerHeight;590 }591 else 592 if (document.documentElement && document.documentElement.clientHeight)593 {// Explorer 6 Strict Mode594 x = document.documentElement.clientWidth;595 y = document.documentElement.clientHeight;596 }597 else598 if (document.body)599 {// other Explorers600 x = document.body.clientWidth;601 y = document.body.clientHeight;602 }603 var el=document.getElementById('loader');604 if(null!=el)605 {606 var top = (y/2) - 50;607 var left = (x/2) - 150;608 if( left<=0 ) left = 10;609 el.style.visibility = (fl==1)?'visible':'hidden';610 el.style.display = (fl==1)?'block':'none';611 el.style.left = left + "px"612 el.style.top = top + "px";613 el.style.zIndex = 2;614 }...

Full Screen

Full Screen

test_p432_all_o1_ds.py

Source:test_p432_all_o1_ds.py Github

copy

Full Screen

1# coding: utf-82__author__ = '代码会说话'3"""4LeetCode 432. 全 O(1) 的数据结构双向链表+哈希算法详解 by 代码会说话5实现一个数据结构支持以下操作:6Inc(key) - 插入一个新的值为 1 的 key。或者使一个存在的 key 增加一,保证 key 不为空字符串。7Dec(key) - 如果这个 key 的值是 1,那么把他从数据结构中移除掉。否者使一个存在的 key 值减一。如果这个 key 不存在,这个函数不做任何事情。key 保证不为空字符串。8GetMaxKey() - 返回 key 中值最大的任意一个。如果没有元素存在,返回一个空字符串""。9GetMinKey() - 返回 key 中值最小的任意一个。如果没有元素存在,返回一个空字符串""。10挑战:以 O(1) 的时间复杂度实现所有操作。11"""12class KeyValue:13 """ 双向链接表的节点数据结构 """14 def __init__(self,key:str):15 self.key = key16 self.value = 117 self.next = None # type: KeyValue18 self.prev = None # type: KeyValue19class AllOne:20 def __init__(self):21 # 3,2,122 self.head = None # type: KeyValue23 self.last = None # type: KeyValue24 self.key_to_keyvalue = {}25 # 3,226 # 3,2,127 def deleteKeyValue(self,kv:KeyValue):28 """删除链表节点"""29 is_head = kv.prev is None30 is_last = kv.next is None31 prev = kv.prev32 next = kv.next33 if is_last and is_head:34 self.head = None35 self.last = None36 elif is_head:37 self.head = next38 self.head.prev = None39 elif is_last:40 prev.next = None41 self.last = prev42 else:43 prev.next = next44 next.prev = prev45 def append(self,kv:KeyValue):46 if self.last:47 self.last.next = kv48 kv.prev = self.last49 self.last = kv50 else:51 self.head = kv52 self.last = kv53 def insertHead(self, kv:KeyValue):54 if self.head is None:55 return self.append(kv)56 # [3] 257 kv.next = self.head58 self.head.prev = kv59 self.head = kv60 kv.prev = None61 def insertAfter(self,p:KeyValue,kv:KeyValue):62 # 363 p_next = p.next64 if p_next is None:65 return self.append(kv)66 kv.next = p_next67 p_next.prev = kv68 p.next = kv69 kv.prev = p70 def insertBefore(self, p:KeyValue,kv:KeyValue):71 # 3,172 p_prev = p.prev73 if p_prev is None:74 self.insertHead(kv)75 else:76 self.insertAfter(p_prev, kv)77 def inc(self, key:str):78 # O(1)79 kv = self.key_to_keyvalue.get(key) # type: KeyValue80 if kv is None:81 kv = KeyValue(key)82 self.key_to_keyvalue[key] = kv83 return self.append(kv)84 kv.value += 185 # 2,2,2,2,1,286 prev = kv.prev87 if not prev:88 return89 # 向左走90 self.deleteKeyValue(kv)91 while prev:92 if prev.value < kv.value:93 prev = prev.prev94 else:95 break96 if prev:97 self.insertAfter(prev, kv)98 else:99 self.insertHead(kv)100 def dec(self, key:str):101 kv = self.key_to_keyvalue.get(key) # type: KeyValue102 if kv is None:103 return104 kv.value -=1105 if kv.value == 0:106 del self.key_to_keyvalue[key]107 self.deleteKeyValue(kv)108 return109 # 4,3,1,2,2,1110 next = kv.next111 if next is None:112 return113 # 向右走114 self.deleteKeyValue(kv)115 while next:116 if next.value > kv.value:117 next = next.next118 else:119 break120 if next is None:121 self.append(kv)122 else:123 self.insertBefore(next,kv)124 def getMaxKey(self):125 if self.head:126 return self.head.key127 return ""128 def getMinKey(self):129 if self.last:130 return self.last.key131 return ""132def test():133 # 测试用例1134 a1 = AllOne()135 a1.inc("a")136 a1.inc("b")137 a1.inc("b")138 a1.inc("c")139 a1.inc("c")140 a1.inc("c")141 a1.dec("b")142 a1.dec("b")143 assert a1.getMinKey() == "a"144 a1.dec("a")145 assert a1.getMinKey() == "c"146 assert a1.getMaxKey() == "c"147 # 测试用例2148 a2 = AllOne()149 a2.inc("san")150 assert a2.getMaxKey() == "san";151 assert a2.getMinKey() == "san";152 a2.inc("san")153 a2.inc("yan")154 assert a2.getMaxKey() == "san";155 assert a2.getMinKey() == "yan";156 a2.dec("yan")157 assert a2.getMaxKey() == "san";158 assert a2.getMinKey() == "san";159 # 测试用例3160 a3 = AllOne()161 a3.inc("san")162 a3.dec("san")163 assert a3.getMaxKey() == "";164 assert a3.getMinKey() == "";165 # 测试用例4166 a4 = AllOne()167 a4.inc("hello")168 a4.inc("goodbye")169 a4.inc("hello")170 a4.inc("hello")171 assert a4.getMaxKey() == "hello"172 a4.inc("leet")173 a4.inc("code")174 a4.inc("leet")175 a4.dec("hello")176 a4.inc("leet")177 a4.inc("code")178 a4.inc("code")179 assert a4.getMaxKey() == "leet"180 # 测试用例5181 a5 = AllOne()182 a5.inc("hello")183 a5.inc("hello")184 a5.inc("world")185 a5.inc("world")186 a5.inc("hello")187 a5.dec("world")188 assert a5.getMaxKey() == "hello"...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run tox automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful