最近在开发和维护一个后台测试系统,专门针对KVM和Xen的patch进行自动化测试,基本功能已经可以正常工作了,这一个月左右的工作可以暂告一段落。Patch测试系统的前台UI是一个网页,让用户(developer)去提交KVM、Xen、Linux、QEMU的patch,然后系统会自动测试,将结果发给developer。今天在对该系统进行简单测试时,发现一个问题,就是我们定义了几个测试场景(scenario),系统中总共有几台机器(test box)供测试,但是有的场景必须在其中1台或两台上测试,而后台自动调度系统还不完善,自动调度不好用,如果选择自动调度机器去测试则会出现测试场景和机器不匹配的情况。当然做一个后台的比较智能的测试调度器也是我明年考虑做的一个东西。而作为临时解决问题且效果较好的做法是,在选择测试场景的下拉列表时,自动关联测试机器的下拉列表,所以今天花了几乎一整天的时间用javascript来做了这个事情(JS大牛会笑话我的,可惜我对JS不熟,实现代码和测试功能时也遇到各种bug)。
首先,看一下patch测试系统的基本界面吧。
用javascript实现了其中两个下拉框的关联(test scenario 和 test box)。我在实现的过程中,尽量做到代码干净优雅,将javascript和html代码分离,且在html中的元素避免使用“onclink”、“onchange”等方法。在HTML中只需要有一段引入javascript文件的代码即可,如下:
XHTML
1
贴一下我实现的javascript的代码(option-association.js)吧,一天的心血啊。自己做的过程中遇到的较大的bug有:1. IE、Firefox对attachEvent、addEventListener方法的支持不同; 2. 清空下拉列表时,最初我写的代码是有bug的,有部分元素未被清空。
JavaScript
function boxes_empty(box_options) {
//for(i=0; i
for(m=box_options.length-1; m>=0; m--) {
box_options[m] = null;
}
}
function boxes_evaluation(box_options, group, type) {
for(i=0; i
box_options[i] = new Option(group[type][i].text, group[type][i].value);
}
}
function scen_box() {
var scen_options = document.getElementById("scenario").options;
var box_options = document.getElementById("test_box").options;
var boxes = new Array();
// init all the available options for test boxes
boxes[0] = new Option("Auto Scheduling", "");
boxes[1] = new Option("VT-NHM6", "VT-NHM6");
boxes[2] = new Option("VT-DP5", "VT-DP5");
boxes[3] = new Option("VT-SNB6", "VT-SNB6");
// group[0] is 'all', group[1] is 'VT-d', group[2] is 'SR-IOV'.
var type_count = 3;
var all = 0;
var vtd = 1;
var sriov = 2;
var group=new Array(type_count)
for (i=0; i
group[i]=new Array();
}
for (i=0; i
group[all][i] = boxes[i];
}
group[vtd][0] = boxes[1];
group[vtd][1] = boxes[2];
group[sriov][0] = boxes[1];
// set the type of the box group. (sriov, vtd, or all)
var type = all;
var scen_index = document.getElementById("scenario").selectedIndex;
var scen_selected = scen_options[scen_index].value.toLowerCase()
if ( scen_selected.indexOf("sriov") >= 0 || scen_selected.indexOf("nightly") >=0 || scen_selected.indexOf("full") >= 0 )
type = sriov;
else if (scen_selected.indexOf("vtd") >= 0 )
type = vtd;
else
type = all;
boxes_empty(box_options)
boxes_evaluation(box_options, group, type)
}
function load() {
var scen_obj = document.getElementById("scenario");
// Firefox or Chrome support addEventListener; IE supports attachEvent.
if (scen_obj.addEventListener) {
scen_obj.addEventListener("change", scen_box);
}
else {
scen_obj.attachEvent("onchange", scen_box);
}
}
if (window.addEventListener) {
window.addEventListener('load', load);
} else if (window.attachEvent) {
window.attachEvent('onload', load);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
functionboxes_empty(box_options){
//for(i=0; i
for(m=box_options.length-1;m>=0;m--){
box_options[m]=null;
}
}
functionboxes_evaluation(box_options,group,type){
for(i=0;i
box_options[i]=newOption(group[type][i].text,group[type][i].value);
}
}
functionscen_box(){
varscen_options=document.getElementById("scenario").options;
varbox_options=document.getElementById("test_box").options;
varboxes=newArray();
// init all the available options for test boxes
boxes[0]=newOption("Auto Scheduling","");
boxes[1]=newOption("VT-NHM6","VT-NHM6");
boxes[2]=newOption("VT-DP5","VT-DP5");
boxes[3]=newOption("VT-SNB6","VT-SNB6");
// group[0] is 'all', group[1] is 'VT-d', group[2] is 'SR-IOV'.
vartype_count=3;
varall=0;
varvtd=1;
varsriov=2;
vargroup=newArray(type_count)
for(i=0;i
group[i]=newArray();
}
for(i=0;i
group[all][i]=boxes[i];
}
group[vtd][0]=boxes[1];
group[vtd][1]=boxes[2];
group[sriov][0]=boxes[1];
// set the type of the box group. (sriov, vtd, or all)
vartype=all;
varscen_index=document.getElementById("scenario").selectedIndex;
varscen_selected=scen_options[scen_index].value.toLowerCase()
if(scen_selected.indexOf("sriov")>=0||scen_selected.indexOf("nightly")>=0||scen_selected.indexOf("full")>=0)
type=sriov;
elseif(scen_selected.indexOf("vtd")>=0)
type=vtd;
else
type=all;
boxes_empty(box_options)
boxes_evaluation(box_options,group,type)
}
functionload(){
varscen_obj=document.getElementById("scenario");
// Firefox or Chrome support addEventListener; IE supports attachEvent.
if(scen_obj.addEventListener){
scen_obj.addEventListener("change",scen_box);
}
else{
scen_obj.attachEvent("onchange",scen_box);
}
}
if(window.addEventListener){
window.addEventListener('load',load);
}elseif(window.attachEvent){
window.attachEvent('onload',load);
}
参考资料:
(js与html的分离)http://www.cnblogs.com/Fskjb/archive/2010/02/26/1674559.html
(js与html的分离)http://blog.csdn.net/eengel/article/details/6193209
(Firebug调试js)http://www.blogjava.net/vincent/archive/2009/04/14/265591.html
(借鉴了aeoril的回答)http://stackoverflow.com/questions/12572404/attachevent-cant-use-this-javascript
w3schools依然是学习html、javascript、CSS、XML、PHP、JQuery等Web技术应该参考的网站。
http://www.w3schools.com/jsref/dom_obj_event.asp
http://www.w3schools.com/html/html_forms.asp