View | Details | Raw Unified | Return to bug 58165
Collapse All | Expand All

(-)C:/perso_max/workspace/JMeter_2.12/src/core/org/apache/jmeter/engine/DistributedRunner.java (-293 / +272 lines)
Lines 1-292 Link Here
1
/*
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
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
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
7
 * the License.  You may obtain a copy of the License at
8
 *
8
 *
9
 *   http://www.apache.org/licenses/LICENSE-2.0
9
 *   http://www.apache.org/licenses/LICENSE-2.0
10
 *
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
15
 * limitations under the License.
16
 *
16
 *
17
 */
17
 */
18
18
19
package org.apache.jmeter.engine;
19
package org.apache.jmeter.engine;
20
20
21
import java.io.IOException;
21
import java.io.IOException;
22
import java.io.OutputStream;
22
import java.io.OutputStream;
23
import java.io.PrintStream;
23
import java.io.PrintStream;
24
import java.net.MalformedURLException;
24
import java.net.MalformedURLException;
25
import java.rmi.NotBoundException;
25
import java.rmi.NotBoundException;
26
import java.rmi.RemoteException;
26
import java.rmi.RemoteException;
27
import java.util.Collection;
27
import java.util.Collection;
28
import java.util.Date;
28
import java.util.Date;
29
import java.util.HashMap;
29
import java.util.HashMap;
30
import java.util.LinkedList;
30
import java.util.LinkedList;
31
import java.util.List;
31
import java.util.List;
32
import java.util.Map;
32
import java.util.Map;
33
import java.util.Properties;
33
import java.util.Properties;
34
34
35
import org.apache.jmeter.util.JMeterUtils;
35
import org.apache.jmeter.util.JMeterUtils;
36
import org.apache.jorphan.collections.HashTree;
36
import org.apache.jorphan.collections.HashTree;
37
import org.apache.jorphan.logging.LoggingManager;
37
import org.apache.jorphan.logging.LoggingManager;
38
import org.apache.log.Logger;
38
import org.apache.log.Logger;
39
39
40
/**
40
/**
41
 * This class serves all responsibility of starting and stopping distributed tests.
41
 * This class serves all responsibility of starting and stopping distributed tests.
42
 * It was refactored from JMeter and RemoteStart classes to unify retry behavior.
42
 * It was refactored from JMeter and RemoteStart classes to unify retry behavior.
43
 *
43
 *
44
 * @see org.apache.jmeter.JMeter
44
 * @see org.apache.jmeter.JMeter
45
 * @see org.apache.jmeter.gui.action.RemoteStart
45
 * @see org.apache.jmeter.gui.action.RemoteStart
46
 */
46
 */
47
public class DistributedRunner {
47
public class DistributedRunner {
48
    private static final Logger log = LoggingManager.getLoggerForClass();
48
    private static final Logger log = LoggingManager.getLoggerForClass();
49
49
50
    public static final String RETRIES_NUMBER = "client.tries"; // $NON-NLS-1$
50
    public static final String RETRIES_NUMBER = "client.tries"; // $NON-NLS-1$
51
    public static final String RETRIES_DELAY = "client.retries_delay"; // $NON-NLS-1$
51
    public static final String RETRIES_DELAY = "client.retries_delay"; // $NON-NLS-1$
52
    public static final String CONTINUE_ON_FAIL = "client.continue_on_fail"; // $NON-NLS-1$
52
    public static final String CONTINUE_ON_FAIL = "client.continue_on_fail"; // $NON-NLS-1$
53
53
54
    private final Properties remoteProps;
54
    private final Properties remoteProps;
55
    private final boolean continueOnFail;
55
    private final boolean continueOnFail;
56
    private final int retriesDelay;
56
    private final int retriesDelay;
57
    private final int retriesNumber;
57
    private final int retriesNumber;
58
    private PrintStream stdout = new PrintStream(new SilentOutputStream());
58
    private PrintStream stdout = new PrintStream(new SilentOutputStream());
59
    private PrintStream stderr = new PrintStream(new SilentOutputStream());
59
    private PrintStream stderr = new PrintStream(new SilentOutputStream());
60
    private final Map<String, JMeterEngine> engines = new HashMap<String, JMeterEngine>();
60
    private final Map<String, JMeterEngine> engines = new HashMap<String, JMeterEngine>();
61
61
62
62
63
    public DistributedRunner() {
63
    public DistributedRunner() {
64
        this(new Properties());
64
        this(new Properties());
65
    }
65
    }
66
66
67
    public DistributedRunner(Properties props) {
67
    public DistributedRunner(Properties props) {
68
        remoteProps = props;
68
        remoteProps = props;
69
        retriesNumber = JMeterUtils.getPropDefault(RETRIES_NUMBER, 1);
69
        retriesNumber = JMeterUtils.getPropDefault(RETRIES_NUMBER, 1);
70
        continueOnFail = JMeterUtils.getPropDefault(CONTINUE_ON_FAIL, false);
70
        continueOnFail = JMeterUtils.getPropDefault(CONTINUE_ON_FAIL, false);
71
        retriesDelay = JMeterUtils.getPropDefault(RETRIES_DELAY, 5000);
71
        retriesDelay = JMeterUtils.getPropDefault(RETRIES_DELAY, 5000);
72
    }
72
    }
73
73
74
    public void init(List<String> addresses, HashTree tree) {
74
    public void init(List<String> addresses, HashTree tree) {
75
        // converting list into mutable version
75
        // converting list into mutable version
76
        List<String> addrs = new LinkedList<String>(addresses);
76
        List<String> addrs = new LinkedList<String>(addresses);
77
77
78
        for (int tryNo = 0; tryNo < retriesNumber; tryNo++) {
78
        for (int tryNo = 0; tryNo < retriesNumber; tryNo++) {
79
            if (tryNo > 0) {
79
            if (tryNo > 0) {
80
                println("Following remote engines will retry configuring: " + addrs);
80
                println("Following remote engines will retry configuring: " + addrs);
81
                println("Pausing before retry for " + retriesDelay + "ms");
81
                println("Pausing before retry for " + retriesDelay + "ms");
82
                try {
82
                try {
83
                    Thread.sleep(retriesDelay);
83
                    Thread.sleep(retriesDelay);
84
                } catch (InterruptedException e) {
84
                } catch (InterruptedException e) {
85
                    throw new RuntimeException("Interrupted while initializing remote", e);
85
                    throw new RuntimeException("Interrupted while initializing remote", e);
86
                }
86
                }
87
            }
87
            }
88
88
89
            int idx = 0;
89
            int idx = 0;
90
            while (idx < addrs.size()) {
90
            while (idx < addrs.size()) {
91
                String address = addrs.get(idx);
91
                String address = addrs.get(idx);
92
                println("Configuring remote engine: " + address);
92
                println("Configuring remote engine: " + address);
93
                JMeterEngine engine = getClientEngine(address.trim(), tree);
93
                JMeterEngine engine = getClientEngine(address.trim(), tree);
94
                if (engine != null) {
94
                if (engine != null) {
95
                    engines.put(address, engine);
95
                    engines.put(address, engine);
96
                    addrs.remove(address);
96
                    addrs.remove(address);
97
                } else {
97
                } else {
98
                    println("Failed to configure " + address);
98
                    println("Failed to configure " + address);
99
                    idx++;
99
                    idx++;
100
                }
100
                }
101
            }
101
            }
102
102
103
            if (addrs.size() == 0) {
103
            if (addrs.size() == 0) {
104
                break;
104
                break;
105
            }
105
            }
106
        }
106
        }
107
107
108
        if (addrs.size() > 0) {
108
        if (addrs.size() > 0) {
109
            String msg = "Following remote engines could not be configured:" + addrs;
109
            String msg = "Following remote engines could not be configured:" + addrs;
110
            if (!continueOnFail || engines.size() == 0) {
110
            if (!continueOnFail || engines.size() == 0) {
111
                stop();
111
                stop();
112
                throw new RuntimeException(msg);
112
                throw new RuntimeException(msg);
113
            } else {
113
            } else {
114
                println(msg);
114
                println(msg);
115
                println("Continuing without failed engines...");
115
                println("Continuing without failed engines...");
116
            }
116
            }
117
        }
117
        }
118
    }
118
    }
119
119
120
    /**
120
    /**
121
     * Starts a remote testing engines
121
     * Starts a remote testing engines
122
     *
122
     *
123
     * @param addresses list of the DNS names or IP addresses of the remote testing engines
123
     * @param addresses list of the DNS names or IP addresses of the remote testing engines
124
     */
124
     */
125
    public void start(List<String> addresses) {
125
    public void start(List<String> addresses) {
126
        println("Starting remote engines");
126
        println("Starting remote engines");
127
        long now = System.currentTimeMillis();
127
        long now = System.currentTimeMillis();
128
        
128
        println("Starting the test @ " + new Date(now) + " (" + now + ")");
129
        
129
        for (String address : addresses) {
130
        println("Starting the test @ " + new Date(now) + " (" + now + ")");
130
            try {
131
       
131
                if (engines.containsKey(address)) {
132
        GuiPackage gp =GuiPackage.getInstance();
132
                    engines.get(address).runTest();
133
        if (gp != null) {// check there is a GUI
133
                } else {
134
        	gp.getMainFrame().startTimer();
134
                    log.warn("Host not found in list of active engines: " + address);
135
        }
135
                }
136
        
136
            } catch (IllegalStateException | JMeterEngineException e) {
137
        for (String address : addresses) {
137
                JMeterUtils.reportErrorToUser(e.getMessage(), JMeterUtils.getResString("remote_error_starting")); // $NON-NLS-1$
138
            try {
138
            }
139
                if (engines.containsKey(address)) {
139
        }
140
                    engines.get(address).runTest();
140
        println("Remote engines have been started");
141
                } else {
141
    }
142
                    log.warn("Host not found in list of active engines: " + address);
142
143
                }
143
    /**
144
            } catch (IllegalStateException | JMeterEngineException e) {
144
     * Start all engines that were previously initiated
145
                JMeterUtils.reportErrorToUser(e.getMessage(), JMeterUtils.getResString("remote_error_starting")); // $NON-NLS-1$
145
     */
146
            }
146
    public void start() {
147
        }
147
        List<String> addresses = new LinkedList<String>();
148
        println("Remote engines have been started");
148
        addresses.addAll(engines.keySet());
149
    }
149
        start(addresses);
150
150
    }
151
    /**
151
152
     * Start all engines that were previously initiated
152
    public void stop(List<String> addresses) {
153
     */
153
        println("Stopping remote engines");
154
    public void start() {
154
        for (String address : addresses) {
155
        List<String> addresses = new LinkedList<String>();
155
            try {
156
        addresses.addAll(engines.keySet());
156
                if (engines.containsKey(address)) {
157
        start(addresses);
157
                    engines.get(address).stopTest(true);
158
    }
158
                } else {
159
159
                    log.warn("Host not found in list of active engines: " + address);
160
    public void stop(List<String> addresses) {
160
                }
161
        println("Stopping remote engines");
161
            } catch (RuntimeException e) {
162
        GuiPackage gp =GuiPackage.getInstance();
162
                errln("Failed to stop test on " + address, e);
163
        if (gp != null) {// check there is a GUI
163
            }
164
        	gp.getMainFrame().stopTimer();
164
        }
165
        }
165
        println("Remote engines have been stopped");
166
        for (String address : addresses) {
166
    }
167
            try {
167
168
                if (engines.containsKey(address)) {
168
    /**
169
                    engines.get(address).stopTest(true);
169
     * Stop all engines that were previously initiated
170
                } else {
170
     */
171
                    log.warn("Host not found in list of active engines: " + address);
171
    public void stop() {
172
                }
172
        List<String> addresses = new LinkedList<String>();
173
            } catch (RuntimeException e) {
173
        addresses.addAll(engines.keySet());
174
                errln("Failed to stop test on " + address, e);
174
        stop(addresses);
175
            }
175
    }
176
        }
176
177
        println("Remote engines have been stopped");
177
    public void shutdown(List<String> addresses) {
178
    }
178
        println("Shutting down remote engines");
179
179
        for (String address : addresses) {
180
    /**
180
            try {
181
     * Stop all engines that were previously initiated
181
                if (engines.containsKey(address)) {
182
     */
182
                    engines.get(address).stopTest(false);
183
    public void stop() {
183
                } else {
184
        List<String> addresses = new LinkedList<String>();
184
                    log.warn("Host not found in list of active engines: " + address);
185
        addresses.addAll(engines.keySet());
185
                }
186
        stop(addresses);
186
187
    }
187
            } catch (RuntimeException e) {
188
188
                errln("Failed to shutdown test on " + address, e);
189
    public void shutdown(List<String> addresses) {
189
            }
190
        println("Shutting down remote engines");
190
        }
191
        GuiPackage gp =GuiPackage.getInstance();
191
        println("Remote engines have been shut down");
192
        if (gp != null) {// check there is a GUI
192
    }
193
        	gp.getMainFrame().stopTimer();
193
194
        }
194
    public void exit(List<String> addresses) {
195
        for (String address : addresses) {
195
        println("Exiting remote engines");
196
            try {
196
        for (String address : addresses) {
197
                if (engines.containsKey(address)) {
197
            try {
198
                    engines.get(address).stopTest(false);
198
                if (engines.containsKey(address)) {
199
                } else {
199
                    engines.get(address).exit();
200
                    log.warn("Host not found in list of active engines: " + address);
200
                } else {
201
                }
201
                    log.warn("Host not found in list of active engines: " + address);
202
202
                }
203
            } catch (RuntimeException e) {
203
            } catch (RuntimeException e) {
204
                errln("Failed to shutdown test on " + address, e);
204
                errln("Failed to exit on " + address, e);
205
            }
205
            }
206
        }
206
        }
207
        println("Remote engines have been shut down");
207
        println("Remote engines have been exited");
208
    }
208
    }
209
209
210
    public void exit(List<String> addresses) {
210
    private JMeterEngine getClientEngine(String address, HashTree testTree) {
211
        println("Exiting remote engines");
211
        JMeterEngine engine;
212
        GuiPackage gp =GuiPackage.getInstance();
212
        try {
213
        if (gp != null) {// check there is a GUI
213
            engine = createEngine(address);
214
        	gp.getMainFrame().stopTimer();
214
            engine.configure(testTree);
215
        }
215
            if (!remoteProps.isEmpty()) {
216
        for (String address : addresses) {
216
                engine.setProperties(remoteProps);
217
            try {
217
            }
218
                if (engines.containsKey(address)) {
218
            return engine;
219
                    engines.get(address).exit();
219
        } catch (Exception ex) {
220
                } else {
220
            log.error("Failed to create engine at " + address, ex);
221
                    log.warn("Host not found in list of active engines: " + address);
221
            JMeterUtils.reportErrorToUser(ex.getMessage(),
222
                }
222
                    JMeterUtils.getResString("remote_error_init") + ": " + address); // $NON-NLS-1$ $NON-NLS-2$
223
            } catch (RuntimeException e) {
223
            return null;
224
                errln("Failed to exit on " + address, e);
224
        }
225
            }
225
    }
226
        }
226
227
        println("Remote engines have been exited");
227
    /**
228
    }
228
     * A factory method that might be overridden for unit testing
229
229
     *
230
    private JMeterEngine getClientEngine(String address, HashTree testTree) {
230
     * @param address address for engine
231
        JMeterEngine engine;
231
     * @return engine instance
232
        try {
232
     * @throws RemoteException
233
            engine = createEngine(address);
233
     * @throws NotBoundException
234
            engine.configure(testTree);
234
     * @throws MalformedURLException
235
            if (!remoteProps.isEmpty()) {
235
     */
236
                engine.setProperties(remoteProps);
236
    protected JMeterEngine createEngine(String address) throws RemoteException, NotBoundException, MalformedURLException {
237
            }
237
        return new ClientJMeterEngine(address);
238
            return engine;
238
    }
239
        } catch (Exception ex) {
239
240
            log.error("Failed to create engine at " + address, ex);
240
    private void println(String s) {
241
            JMeterUtils.reportErrorToUser(ex.getMessage(),
241
        log.info(s);
242
                    JMeterUtils.getResString("remote_error_init") + ": " + address); // $NON-NLS-1$ $NON-NLS-2$
242
        stdout.println(s);
243
            return null;
243
    }
244
        }
244
245
    }
245
    private void errln(String s, Exception e) {
246
246
        log.error(s, e);
247
    /**
247
        stderr.println(s + ": ");
248
     * A factory method that might be overridden for unit testing
248
        e.printStackTrace(stderr);
249
     *
249
    }
250
     * @param address address for engine
250
251
     * @return engine instance
251
    public void setStdout(PrintStream stdout) {
252
     * @throws RemoteException
252
        this.stdout = stdout;
253
     * @throws NotBoundException
253
    }
254
     * @throws MalformedURLException
254
255
     */
255
    public void setStdErr(PrintStream stdErr) {
256
    protected JMeterEngine createEngine(String address) throws RemoteException, NotBoundException, MalformedURLException {
256
        this.stderr = stdErr;
257
        return new ClientJMeterEngine(address);
257
    }
258
    }
258
259
259
    private static class SilentOutputStream extends OutputStream {
260
    private void println(String s) {
260
        @Override
261
        log.info(s);
261
        public void write(int b) throws IOException {
262
        stdout.println(s);
262
            // enjoy the silence
263
    }
263
        }
264
264
    }
265
    private void errln(String s, Exception e) {
265
266
        log.error(s, e);
266
    /**
267
        stderr.println(s + ": ");
267
     * @return {@link Collection} of {@link JMeterEngine}
268
        e.printStackTrace(stderr);
268
     */
269
    }
269
    public Collection<? extends JMeterEngine> getEngines() {
270
270
        return engines.values();
271
    public void setStdout(PrintStream stdout) {
271
    }
272
        this.stdout = stdout;
272
}
273
    }
274
275
    public void setStdErr(PrintStream stdErr) {
276
        this.stderr = stdErr;
277
    }
278
279
    private static class SilentOutputStream extends OutputStream {
280
        @Override
281
        public void write(int b) throws IOException {
282
            // enjoy the silence
283
        }
284
    }
285
286
    /**
287
     * @return {@link Collection} of {@link JMeterEngine}
288
     */
289
    public Collection<? extends JMeterEngine> getEngines() {
290
        return engines.values();
291
    }
292
}
293
--
(-)C:/perso_max/workspace/JMeter_2.12/src/core/org/apache/jmeter/gui/MainFrame.java (-41 lines)
Lines 45-46 Link Here
45
import java.text.SimpleDateFormat;
46
import java.util.Date;
Lines 176-177 Link Here
176
    
177
    private JLabel timeRun;
Lines 193-199 Link Here
193
    
194
    private javax.swing.Timer timer = new javax.swing.Timer(1000, new java.awt.event.ActionListener()
195
    {
196
      public void actionPerformed(java.awt.event.ActionEvent e) {
197
    	  CalculTime();
198
      }
199
    });
Lines 215-216 Link Here
215
        
216
        timeRun = new JLabel("00:00:00");
Lines 398-421 Link Here
398
    // Calcul et display time off the loadtest
399
    public void startTimer() {
400
	    timer.start();
401
    }
402
    
403
    public void stopTimer() {
404
    	timer.stop();  	
405
    }
406
    
407
    public void CalculTime() {
408
         long currentTime = System.currentTimeMillis();
409
         long startTime = JMeterContextService.getTestStartTime();
410
         if (startTime == 0)
411
        	 timer.stop();  	
412
         else
413
         {
414
	         long elapse_time_ms = (currentTime - startTime);
415
	         Date elapse_date = new Date(elapse_time_ms);
416
	         SimpleDateFormat df = new java.text.SimpleDateFormat("HH:mm:ss");
417
	         df.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
418
	         timeRun.setText(df.format(elapse_date));
419
         }
420
    }
421
    
Lines 595-598 Link Here
595
        
596
        toolPanel.add(new JLabel("   "));
597
        toolPanel.add(timeRun);
598
        toolPanel.add(new JLabel("   "));
(-)C:/perso_max/workspace/JMeter_2.12/src/core/org/apache/jmeter/engine/StandardJMeterEngine.java (-15 / +1 lines)
Lines 343-345 Link Here
343
            
344
           
345
            
Lines 351-356 Link Here
351
        
352
        GuiPackage gp =GuiPackage.getInstance();
353
        if (gp != null) {// check there is a GUI
354
        	gp.getMainFrame().startTimer();
355
        }
356
        
Line 414 Link Here
414
          
Lines 485-488 Link Here
485
        
449
        JMeterContextService.endTest();
486
        if (gp != null) {// check there is a GUI
487
          	 gp.getMainFrame().stopTimer();
488
        }
489
--

Return to bug 58165