Line 0
Link Here
|
|
|
1 |
/* |
2 |
* Licensed to the Apache Software Foundation (ASF) under one or more |
3 |
* contributor license agreements. See the NOTICE file distributed with |
4 |
* this work for additional information regarding copyright ownership. |
5 |
* The ASF licenses this file to You under the Apache License, Version 2.0 |
6 |
* (the "License"); you may not use this file except in compliance with |
7 |
* the License. You may obtain a copy of the License at |
8 |
* |
9 |
* http://www.apache.org/licenses/LICENSE-2.0 |
10 |
* |
11 |
* Unless required by applicable law or agreed to in writing, software |
12 |
* 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 and |
15 |
* limitations under the License. |
16 |
* |
17 |
*/ |
18 |
|
19 |
package org.apache.jmeter.config; |
20 |
|
21 |
import java.io.BufferedReader; |
22 |
import java.io.IOException; |
23 |
import java.io.StringReader; |
24 |
import java.util.ArrayList; |
25 |
import java.util.List; |
26 |
|
27 |
import org.apache.jmeter.config.ConfigTestElement; |
28 |
import org.apache.jmeter.engine.event.LoopIterationEvent; |
29 |
import org.apache.jmeter.engine.event.LoopIterationListener; |
30 |
import org.apache.jmeter.testbeans.TestBean; |
31 |
import org.apache.jorphan.logging.LoggingManager; |
32 |
import org.apache.jorphan.util.JOrphanUtils; |
33 |
import org.apache.log.Logger; |
34 |
|
35 |
/** |
36 |
* Use this config element when you want to vary the values of some user defined |
37 |
* variables between iterations, i.e. loops. <br> |
38 |
* <br> |
39 |
* This element reads the Data text (CSV or the like) and splits it into rows |
40 |
* and columns. For each iteration, a new row is read, and its columns are |
41 |
* assigned to the user defined variable with the name of the Variable names. <br> |
42 |
* <br> |
43 |
* The rows are just the rows in the text, and the column are separated by the |
44 |
* defined Delimiter. <br> |
45 |
* <br> |
46 |
* Each column gets the name from the comma separated Variable Names, and the |
47 |
* number of Variable Names must be the same as the number of columns in every |
48 |
* row, or else an exception will be thrown. <br> |
49 |
* <br> |
50 |
* When the last row is reached, it will simply start from the top again. |
51 |
* <br><br> |
52 |
* The data is not trimmed, hence any whitespace that is not a delimiter will |
53 |
* remain in the variable when used in the test. |
54 |
* |
55 |
*/ |
56 |
public class TabularDataSet extends ConfigTestElement implements TestBean, |
57 |
LoopIterationListener { |
58 |
private static final long serialVersionUID = 232L; |
59 |
private static final Logger log = LoggingManager.getLoggerForClass(); |
60 |
|
61 |
private transient String variableNames; |
62 |
private transient String delimiter; |
63 |
private transient String data; |
64 |
private transient boolean membersModifiedAndNeedsToBeReparsed = false; |
65 |
|
66 |
private transient String[] variableNamesArray; |
67 |
private transient List<String[]> dataGrid; |
68 |
|
69 |
public void iterationStart(LoopIterationEvent iterEvent) { |
70 |
setUpData(); |
71 |
int lineNumber = iterEvent.getIteration() % dataGrid.size(); |
72 |
String[] row = dataGrid.get(lineNumber); |
73 |
for (int i = 0; i < row.length; i++) { |
74 |
String rowItem = row[i]; |
75 |
getThreadContext().getVariables().put(variableNamesArray[i], rowItem); |
76 |
} |
77 |
} |
78 |
|
79 |
public String getVariableNames() { |
80 |
return variableNames; |
81 |
} |
82 |
|
83 |
public void setVariableNames(String variableNames) { |
84 |
this.variableNames = variableNames; |
85 |
membersModifiedAndNeedsToBeReparsed = true; |
86 |
} |
87 |
|
88 |
public String getDelimiter() { |
89 |
return delimiter; |
90 |
} |
91 |
|
92 |
public void setDelimiter(String delimiter) { |
93 |
this.delimiter = delimiter; |
94 |
membersModifiedAndNeedsToBeReparsed = true; |
95 |
} |
96 |
|
97 |
public String getData() { |
98 |
return data; |
99 |
} |
100 |
|
101 |
public void setData(String value) { |
102 |
this.data = value; |
103 |
membersModifiedAndNeedsToBeReparsed = true; |
104 |
} |
105 |
|
106 |
private void setUpData() { |
107 |
if (!membersModifiedAndNeedsToBeReparsed) { |
108 |
return; |
109 |
} |
110 |
|
111 |
try { |
112 |
variableNamesArray = JOrphanUtils.split(variableNames, ","); |
113 |
dataGrid = new ArrayList<String[]>(); |
114 |
BufferedReader bufferedReader = new BufferedReader( |
115 |
new StringReader(data)); |
116 |
String row = null; |
117 |
int lineNumber = 1; |
118 |
while ((row = bufferedReader.readLine()) != null) { |
119 |
String[] rowElements = JOrphanUtils.split(row, getActualDelimiter()); |
120 |
assertThatDimensionsOfVariableNamesAndRowAreSame(lineNumber, rowElements); |
121 |
dataGrid.add(rowElements); |
122 |
lineNumber++; |
123 |
} |
124 |
membersModifiedAndNeedsToBeReparsed = false; |
125 |
} catch (IOException e) { |
126 |
log.error("Could not parse data", e); |
127 |
} |
128 |
} |
129 |
|
130 |
private void assertThatDimensionsOfVariableNamesAndRowAreSame(int line, |
131 |
String[] rowElements) { |
132 |
if (rowElements.length != variableNamesArray.length) { |
133 |
String explicitErrorMessage = |
134 |
"Data on line " + line + " has " |
135 |
+ rowElements.length + " columns " + "but require " |
136 |
+ variableNamesArray.length + " columns (" |
137 |
+ variableNames + ")\n" + "Note that delimiter is " |
138 |
+ getDelimiter(); |
139 |
throw new RuntimeException(explicitErrorMessage); |
140 |
} |
141 |
} |
142 |
|
143 |
private String getActualDelimiter() { |
144 |
if (delimiter.equals("\\t")) { |
145 |
return "\t"; |
146 |
} |
147 |
return delimiter; |
148 |
} |
149 |
|
150 |
} |