Testcase generation tool for combinatorial interaction testing
Révision | 8a4cc78799d484f5c73c4f6cb5d1305c515616fc (tree) |
---|---|
l'heure | 2015-10-16 11:48:47 |
Auteur | t-tutiya <tatsuhiro@ieee...> |
Commiter | t-tutiya |
Support of arithmetic comparison, including < > <= >= ===.
@@ -17,7 +17,7 @@ class ConstraintHandler { | ||
17 | 17 | |
18 | 18 | ConstraintHandler(PList parameterList, List<Node> constraintList) { |
19 | 19 | bdd = new BDD(sizeOfNodetable, sizeOfCache); |
20 | - // bdd = new jdd.bdd.debug.DebugBDD(1000,1000); | |
20 | + bdd = new jdd.bdd.debug.DebugBDD(1000,1000); | |
21 | 21 | |
22 | 22 | // parameterÌXg |
23 | 23 | parameters = setBDDforParameter(parameterList); |
@@ -142,6 +142,49 @@ class ConstraintHandler { | ||
142 | 142 | return f; |
143 | 143 | } |
144 | 144 | |
145 | + | |
146 | + private int setBddConstraintNewBuggy(List<Node> constraintList) { | |
147 | + int f = bdd.getOne(); | |
148 | + bdd.ref(f); | |
149 | + | |
150 | + // §ñ®Ì_ÏðÆé | |
151 | + for (Node n : constraintList) { | |
152 | + int g = n.evaluate(bdd, parameters); | |
153 | + int tmp = bdd.ref(bdd.and(f, g)); | |
154 | + bdd.deref(f); | |
155 | + bdd.deref(g); | |
156 | + f = tmp; | |
157 | + } | |
158 | + | |
159 | + // p[^Å©íÈ¢ÌæðfalseÉ·é | |
160 | + int fordebug = 0; | |
161 | + for (VariableAndBDD vb : parameters) { | |
162 | + int cube = vb.var[0]; | |
163 | + bdd.ref(cube); | |
164 | + for (int i = 1; i < vb.var.length; i++) { | |
165 | + int tmp = bdd.ref(bdd.and(cube, vb.var[i])); | |
166 | + bdd.deref(cube); | |
167 | + cube = tmp; | |
168 | + } | |
169 | + int tmp = bdd.ref(bdd.exists(f, cube)); | |
170 | + // §ñÉÖW·éêÌÝ | |
171 | + if (tmp != f) { | |
172 | + fordebug++; | |
173 | + int tmp1 = bdd.ref(bdd.and(f, vb.constraint)); | |
174 | + bdd.deref(f); | |
175 | + f = tmp1; | |
176 | + } | |
177 | + bdd.deref(cube); | |
178 | + bdd.deref(tmp); | |
179 | + } | |
180 | + System.out.println(fordebug); | |
181 | + // *ðtÁ | |
182 | + f = extendBddConstraint(f); | |
183 | + | |
184 | + return f; | |
185 | + } | |
186 | + | |
187 | + | |
145 | 188 | private int extendBddConstraint(int constraint) { |
146 | 189 | int f = constraint; |
147 | 190 | for (VariableAndBDD p : parameters) { |
@@ -132,7 +132,8 @@ class Generator2 extends Generator { | ||
132 | 132 | * Random(randomseed); } |
133 | 133 | */ |
134 | 134 | |
135 | - final int NumOfIterationForEachTest = 20; | |
135 | +// final int NumOfIterationForEachTest = 20; | |
136 | + final int NumOfIterationForEachTest = 1; | |
136 | 137 | |
137 | 138 | Generator2(ParameterModel parametermodel, GList groupList, |
138 | 139 | ConstraintHandler constrainthandler, List<Testcase> seed, |
@@ -49,6 +49,36 @@ public class Parameter { | ||
49 | 49 | return ids; |
50 | 50 | } |
51 | 51 | |
52 | + // numberÆZpIɯ¶ ÌidðÆè¾·¨Â©ÁÄÈ¢ | |
53 | + List<Integer> getID(double number) { | |
54 | + List<Integer> ids = new ArrayList<Integer>(); | |
55 | + for (int i = 0; i < value_name.size(); i++) { | |
56 | + double level; | |
57 | + try { | |
58 | + level = Double.parseDouble(value_name.get(i)); | |
59 | + if (level == number) | |
60 | + ids.add(i); | |
61 | + } catch (NumberFormatException e) {} | |
62 | + } | |
63 | + return ids; | |
64 | + } | |
65 | + | |
66 | + // numberÆZpIÉÖWÌ é ÌidðÆè¾· | |
67 | + // level ` number | |
68 | + List<Integer> getID(double number, RelationOverDoublePair com) { | |
69 | + List<Integer> ids = new ArrayList<Integer>(); | |
70 | + for (int i = 0; i < value_name.size(); i++) { | |
71 | + double level; | |
72 | + try { | |
73 | + level = Double.parseDouble(value_name.get(i)); | |
74 | + if (com.hasRelation(level, number)) | |
75 | + ids.add(i); | |
76 | + } catch (NumberFormatException e) {} | |
77 | + } | |
78 | + return ids; | |
79 | + } | |
80 | + | |
81 | + | |
52 | 82 | } |
53 | 83 | |
54 | 84 | class PList extends LinkedList<Parameter> { |
@@ -13,13 +13,13 @@ public class Parse { | ||
13 | 13 | } |
14 | 14 | |
15 | 15 | public Node parseExpression() { |
16 | - String token = t.peepToken(); | |
16 | + String nextToken = t.peepToken(); | |
17 | 17 | try { |
18 | - if (token == null) { | |
18 | + if (nextToken == null) { | |
19 | 19 | Error.printError(Main.language == Main.Language.JP ? "§ñ®Éëèª èÜ·" |
20 | 20 | : "Invalid constraints"); |
21 | 21 | return null; |
22 | - } else if (token.equals("(")) | |
22 | + } else if (nextToken.equals("(")) | |
23 | 23 | return expressionWithParentheses(); |
24 | 24 | else { |
25 | 25 | // error |
@@ -66,10 +66,10 @@ public class Parse { | ||
66 | 66 | // ZqÌÌg[Nª ( © Ǥ©Å»f |
67 | 67 | // case 1: ( <> ( |
68 | 68 | // case 2: ( <> [ foo, ( <> foo |
69 | - String token = t.peepNextToken(); | |
70 | - if (token == null) | |
69 | + String nextNextToken = t.peepNextToken(); | |
70 | + if (nextNextToken == null) | |
71 | 71 | throw new OutOfTokenStreamException(); |
72 | - if (token.equals("(")) | |
72 | + if (nextNextToken.equals("(")) | |
73 | 73 | return boolExpression(); |
74 | 74 | else |
75 | 75 | return atomExpression(); |
@@ -99,6 +99,7 @@ public class Parse { | ||
99 | 99 | return null; // unreachable |
100 | 100 | } |
101 | 101 | |
102 | + | |
102 | 103 | private Node notExpression() throws OutOfTokenStreamException { |
103 | 104 | BooleanUnaryOperator res = new NotOperator(); |
104 | 105 | t.getToken(); |
@@ -176,6 +177,16 @@ public class Parse { | ||
176 | 177 | return equalityAtomExpression(); |
177 | 178 | else if (token.equals("<>")) |
178 | 179 | return inequalityAtomExpression(); |
180 | + else if (token.equals("===")) | |
181 | + return artithmeticEqualityAtomExpression(new EqualTo(), new EqualTo()); | |
182 | + else if (token.equals("<")) | |
183 | + return artithmeticEqualityAtomExpression(new LessThan(), new GreaterThan()); | |
184 | + else if (token.equals(">")) | |
185 | + return artithmeticEqualityAtomExpression(new GreaterThan(), new LessThan()); | |
186 | + else if (token.equals("<=")) | |
187 | + return artithmeticEqualityAtomExpression(new LTE(), new GTE()); | |
188 | + else if (token.equals(">=")) | |
189 | + return artithmeticEqualityAtomExpression(new GTE(), new LTE()); | |
179 | 190 | else |
180 | 191 | Error.printError(Main.language == Main.Language.JP ? "§ñ®É == © <> ªKvÅ·" |
181 | 192 | : "== or <> expected in constraints"); |
@@ -188,6 +199,69 @@ public class Parse { | ||
188 | 199 | return res; |
189 | 200 | } |
190 | 201 | |
202 | + private Node artithmeticEqualityAtomExpression(RelationOverDoublePair com1, RelationOverDoublePair com2) | |
203 | + throws OutOfTokenStreamException { | |
204 | + // case 1 val1 val2 com1 | |
205 | + // case 2 val1 [para1] com2 | |
206 | + // case 3 [para1] val1 com1 | |
207 | + // case 4 [para1] [para2] com1 | |
208 | + String val1, val2, para1, para2; | |
209 | + String token1, token2; | |
210 | + | |
211 | + token1 = t.peepToken(); | |
212 | + token2 = t.peepNextToken(); | |
213 | + | |
214 | + if (token1 == null || token2 == null) | |
215 | + throw new OutOfTokenStreamException(); | |
216 | + | |
217 | + // case 1 | |
218 | + if ((token1.equals("[") == false) && (token2.equals("[") == false)) { | |
219 | + val1 = t.getToken(); | |
220 | + val2 = t.getToken(); | |
221 | + return compareArithmeticValueAndValue(val1, val2, com1); | |
222 | + } | |
223 | + | |
224 | + // case 2 | |
225 | + if ((token1.equals("[") == false) && (token2.equals("[") == true)) { | |
226 | + val1 = t.getToken(); | |
227 | + t.getToken(); // must be [ | |
228 | + para1 = t.getToken(); | |
229 | + if (t.getToken().equals("]") == false) { | |
230 | + Error.printError(Main.language == Main.Language.JP ? "§ñ®É]ªKvÅ·" | |
231 | + : "] expected in constraints"); | |
232 | + } | |
233 | + return compareArithmeticParameterAndValue(para1, val1, com2); | |
234 | + } | |
235 | + | |
236 | + // case 3, 4 | |
237 | + t.getToken(); // must be "[" | |
238 | + para1 = t.getToken(); | |
239 | + if (t.getToken().equals("]") == false) { | |
240 | + Error.printError(Main.language == Main.Language.JP ? "§ñ®É]ªKvÅ·" | |
241 | + : "] expected in constraints"); | |
242 | + } | |
243 | + token1 = t.peepToken(); | |
244 | + if (token1 == null) | |
245 | + throw new OutOfTokenStreamException(); | |
246 | + | |
247 | + // case 3 | |
248 | + if (token1.equals("[") == false) { | |
249 | + val1 = t.getToken(); | |
250 | + return compareArithmeticParameterAndValue(para1, val1, com1); | |
251 | + } | |
252 | + | |
253 | + // case 4 | |
254 | + t.getToken(); // must be [ | |
255 | + para2 = t.getToken(); | |
256 | + if (t.getToken().equals("]") == false) { | |
257 | + Error.printError(Main.language == Main.Language.JP ? "§ñ®É]ªKvÅ·" | |
258 | + : "] expected in constraints"); | |
259 | + } | |
260 | + return compareArithmeticParameterAndParameter(para1, para2, com1); | |
261 | + } | |
262 | + | |
263 | + | |
264 | + | |
191 | 265 | private Node equalityAtomExpression() throws OutOfTokenStreamException { |
192 | 266 | // case 1 val1 val2 |
193 | 267 | // case 2 val1 [para1] |
@@ -255,6 +329,21 @@ public class Parse { | ||
255 | 329 | return new FalseValue(); |
256 | 330 | } |
257 | 331 | |
332 | + private Node compareArithmeticValueAndValue(String val1, String val2, RelationOverDoublePair com) { | |
333 | + double d1 = 0, d2 = 0; | |
334 | + try { | |
335 | + d1 = Double.parseDouble(val1); | |
336 | + d2 = Double.parseDouble(val2); | |
337 | + } catch (NumberFormatException e) { | |
338 | + Error.printError(Main.language == Main.Language.JP ? "ÅÈ¢¶ñðZpärµÄ¢Ü·" | |
339 | + : "String that cannot be parsed as a number"); | |
340 | + } | |
341 | + if (com.hasRelation(d1, d2)) | |
342 | + return new TrueValue(); | |
343 | + else | |
344 | + return new FalseValue(); | |
345 | + } | |
346 | + | |
258 | 347 | private Node compareParameterAndValue(String para, String val) { |
259 | 348 | int parameterID = 0; |
260 | 349 | Parameter p; |
@@ -298,6 +387,58 @@ public class Parse { | ||
298 | 387 | } |
299 | 388 | } |
300 | 389 | |
390 | + private Node compareArithmeticParameterAndValue(String para, String val, RelationOverDoublePair com) { | |
391 | + int parameterID = 0; | |
392 | + Parameter p; | |
393 | + // int value = 0; | |
394 | + List<Integer> valueIDs = null; | |
395 | + | |
396 | + // öq¼ª³µ¢©`FbN | |
397 | + try { | |
398 | + parameterID = parameterList.getID(para); | |
399 | + } catch (NoParameterNameException e) { | |
400 | + Error.printError(Main.language == Main.Language.JP ? "§ñÌöq¼Éëèª èÜ·" | |
401 | + : "Invalid parameter name in constraints"); | |
402 | + } | |
403 | + p = parameterList.get(parameterID); | |
404 | + | |
405 | + // l¼ª number ÆÈé©`FbN | |
406 | + double number = 0; | |
407 | + try { | |
408 | + number = Double.parseDouble(val); | |
409 | + } catch (NumberFormatException e) { | |
410 | + Error.printError(Main.language == Main.Language.JP ? "ÅÈ¢¶ñðZpärµÄ¢Ü·" | |
411 | + : "String that cannot be parsed as a number"); | |
412 | + } | |
413 | + | |
414 | + // numberÆZpIÉêv·élevelð·×ÄXgÉ¢êé | |
415 | + // -> level ÖW number ÆÈélevelð·×ÄXgÉ | |
416 | + valueIDs = p.getID(number, com); | |
417 | + | |
418 | + // Çêàêv¹¸ | |
419 | + if (valueIDs.size() == 0) { | |
420 | + return new FalseValue(); | |
421 | + } | |
422 | + // l¼Éd¡Èµ | |
423 | + if (valueIDs.size() == 1) { | |
424 | + ComparisonOfParameterAndValue res = new EqualityOfParameterAndValue(); | |
425 | + res.p = parameterID; | |
426 | + res.v = valueIDs.get(0); | |
427 | + return res; | |
428 | + } | |
429 | + // l¼Éd¡ è | |
430 | + else { | |
431 | + BooleanMultinaryOperator res = new OrOperator(); | |
432 | + for (Integer vid : valueIDs) { | |
433 | + ComparisonOfParameterAndValue child = new EqualityOfParameterAndValue(); | |
434 | + child.p = parameterID; | |
435 | + child.v = vid; | |
436 | + res.ChildList.add(child); | |
437 | + } | |
438 | + return res; | |
439 | + } | |
440 | + } | |
441 | + | |
301 | 442 | private Node compareParameterAndParameter(String para1, String para2) { |
302 | 443 | int parameterID1 = 0; |
303 | 444 | int parameterID2 = 0; |
@@ -353,7 +494,7 @@ public class Parse { | ||
353 | 494 | } |
354 | 495 | } |
355 | 496 | |
356 | - // case 3: l¼Å¯¶à̪2ÂÈã | |
497 | + // case 3: l¼Å¯¶à̪2ÂÈã vdebug ½Å case 2ݽ¢ÉµÄÈ¢ÌH | |
357 | 498 | BooleanMultinaryOperator res = new OrOperator(); |
358 | 499 | for (int vid1 = 0; vid1 < p1.value_name.size(); vid1++) { |
359 | 500 | for (int vid2 = 0; vid2 < p2.value_name.size(); vid2++) { |
@@ -374,8 +515,125 @@ public class Parse { | ||
374 | 515 | return res; |
375 | 516 | } |
376 | 517 | |
518 | + private Node compareArithmeticParameterAndParameter(String para1, String para2, RelationOverDoublePair com) { | |
519 | + int parameterID1 = 0; | |
520 | + int parameterID2 = 0; | |
521 | + Parameter p1, p2; | |
522 | + // öq¼ª³µ¢©`FbN | |
523 | + try { | |
524 | + parameterID1 = parameterList.getID(para1); | |
525 | + parameterID2 = parameterList.getID(para2); | |
526 | + } catch (NoParameterNameException e) { | |
527 | + Error.printError(Main.language == Main.Language.JP ? "§ñÌöq¼Éëèª èÜ·" | |
528 | + : "Invalid parameter name in constraints"); | |
529 | + } | |
530 | + p1 = parameterList.get(parameterID1); | |
531 | + p2 = parameterList.get(parameterID2); | |
532 | + | |
533 | + // _uÅÌlªÖWðàÂyAð¦é | |
534 | + int count = 0; | |
535 | + for (String valName1 : p1.value_name) { | |
536 | + for (String valName2 : p2.value_name) { | |
537 | + try { | |
538 | + double num1 = Double.parseDouble(valName1); | |
539 | + double num2 = Double.parseDouble(valName2); | |
540 | + if (com.hasRelation(num1, num2)) | |
541 | + count++; | |
542 | + } catch (NumberFormatException e) { | |
543 | + } | |
544 | + } | |
545 | + } | |
546 | + | |
547 | + // case 1: êv·él¼ªÈ¢ | |
548 | + if (count == 0) | |
549 | + return new FalseValue(); | |
550 | + | |
551 | + // case 2: êv·éàyAªÐÆ | |
552 | + if (count == 1) { | |
553 | + for (String valName1 : p1.value_name) { | |
554 | + for (String valName2 : p2.value_name) { | |
555 | + try { | |
556 | + double num1 = Double.parseDouble(valName1); | |
557 | + double num2 = Double.parseDouble(valName2); | |
558 | + if (com.hasRelation(num1, num2)) { | |
559 | + BooleanMultinaryOperator res = new AndOperator(); | |
560 | + ComparisonOfParameterAndValue sub1 = new EqualityOfParameterAndValue(); | |
561 | + ComparisonOfParameterAndValue sub2 = new EqualityOfParameterAndValue(); | |
562 | + try { | |
563 | + sub1.p = parameterID1; | |
564 | + sub1.v = p1.getID(valName1).get(0).byteValue(); | |
565 | + sub2.p = parameterID2; | |
566 | + sub2.v = p2.getID(valName2).get(0).byteValue(); | |
567 | + } catch (NoValueNameException e) { | |
568 | + Error.printError("Inner error"); | |
569 | + } | |
570 | + res.ChildList.add(sub1); | |
571 | + res.ChildList.add(sub2); | |
572 | + return res; | |
573 | + } | |
574 | + } catch (NumberFormatException e) {} | |
575 | + } // inner for | |
576 | + } // outer for | |
577 | + } | |
578 | + | |
579 | + // case 3: l¼Å¯¶à̪2ÂÈã | |
580 | + BooleanMultinaryOperator res = new OrOperator(); | |
581 | + for (int vid1 = 0; vid1 < p1.value_name.size(); vid1++) { | |
582 | + for (int vid2 = 0; vid2 < p2.value_name.size(); vid2++) { | |
583 | + try { | |
584 | + double num1 = Double.parseDouble(p1.value_name.get(vid1)); | |
585 | + double num2 = Double.parseDouble(p2.value_name.get(vid2)); | |
586 | + if (com.hasRelation(num1, num2)) { | |
587 | + BooleanMultinaryOperator child = new AndOperator(); | |
588 | + ComparisonOfParameterAndValue sub1 = new EqualityOfParameterAndValue(); | |
589 | + ComparisonOfParameterAndValue sub2 = new EqualityOfParameterAndValue(); | |
590 | + sub1.p = parameterID1; | |
591 | + sub1.v = vid1; | |
592 | + sub2.p = parameterID2; | |
593 | + sub2.v = vid2; | |
594 | + child.ChildList.add(sub1); | |
595 | + child.ChildList.add(sub2); | |
596 | + res.ChildList.add(child); | |
597 | + } | |
598 | + } catch (NumberFormatException e) {} | |
599 | + } | |
600 | + } | |
601 | + return res; | |
602 | + } | |
603 | +} | |
604 | + | |
605 | +abstract class RelationOverDoublePair { | |
606 | + abstract boolean hasRelation(double leftval, double rightvalue); | |
607 | +} | |
608 | + | |
609 | +class EqualTo extends RelationOverDoublePair { | |
610 | + boolean hasRelation(double leftval, double rightvalue) { | |
611 | + return leftval == rightvalue ? true : false; | |
612 | + } | |
613 | +} | |
614 | +class LessThan extends RelationOverDoublePair { | |
615 | + boolean hasRelation(double leftval, double rightvalue) { | |
616 | + return leftval < rightvalue ? true : false; | |
617 | + } | |
377 | 618 | } |
378 | 619 | |
620 | +class GreaterThan extends RelationOverDoublePair { | |
621 | + boolean hasRelation(double leftval, double rightvalue) { | |
622 | + return leftval > rightvalue ? true : false; | |
623 | + } | |
624 | +} | |
625 | + | |
626 | +class LTE extends RelationOverDoublePair { | |
627 | + boolean hasRelation(double leftval, double rightvalue) { | |
628 | + return leftval <= rightvalue ? true : false; | |
629 | + } | |
630 | +} | |
631 | + | |
632 | +class GTE extends RelationOverDoublePair { | |
633 | + boolean hasRelation(double leftval, double rightvalue) { | |
634 | + return leftval >= rightvalue ? true : false; | |
635 | + } | |
636 | +} | |
379 | 637 | /* |
380 | 638 | * old one public class Parse { private TokenHandler t; private PList |
381 | 639 | * parameterList; Parse(TokenHandler t, PList parameterList) { this.t = t; |