001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jmeter.junit;
020:
021: import java.io.ByteArrayInputStream;
022: import java.io.ByteArrayOutputStream;
023: import java.io.ObjectInputStream;
024: import java.io.ObjectOutputStream;
025: import java.io.Serializable;
026: import java.rmi.RemoteException;
027: import java.util.Collection;
028: import java.util.HashMap;
029: import java.util.Iterator;
030: import java.util.LinkedList;
031: import java.util.List;
032: import java.util.Locale;
033: import java.util.Map;
034: import java.util.Properties;
035: import java.util.Set;
036:
037: import javax.swing.JComponent;
038:
039: import junit.framework.Test;
040: import junit.framework.TestSuite;
041:
042: import org.apache.jmeter.config.gui.ObsoleteGui;
043: import org.apache.jmeter.engine.util.CompoundVariable;
044: import org.apache.jmeter.functions.Function;
045: import org.apache.jmeter.gui.GuiPackage;
046: import org.apache.jmeter.gui.JMeterGUIComponent;
047: import org.apache.jmeter.gui.UnsharedComponent;
048: import org.apache.jmeter.gui.action.ActionRouter;
049: import org.apache.jmeter.gui.tree.JMeterTreeListener;
050: import org.apache.jmeter.gui.tree.JMeterTreeModel;
051: import org.apache.jmeter.gui.tree.JMeterTreeNode;
052: import org.apache.jmeter.save.SaveService;
053: import org.apache.jmeter.testbeans.TestBean;
054: import org.apache.jmeter.testbeans.gui.TestBeanGUI;
055: import org.apache.jmeter.testelement.TestElement;
056: import org.apache.jmeter.testelement.property.JMeterProperty;
057: import org.apache.jmeter.testelement.property.PropertyIterator;
058: import org.apache.jmeter.util.JMeterUtils;
059: import org.apache.jorphan.logging.LoggingManager;
060: import org.apache.jorphan.reflect.ClassFinder;
061: import org.apache.jorphan.util.JOrphanUtils;
062: import org.apache.log.Logger;
063: import org.jdom.Document;
064: import org.jdom.Element;
065: import org.jdom.input.SAXBuilder;
066:
067: /**
068: * @version $Revision: 541880 $ Last update $Date: 2007-05-26 10:51:07 +0100 (Sat, 26 May 2007) $
069: */
070: public class JMeterTest extends JMeterTestCase {
071: private static Logger log = LoggingManager.getLoggerForClass();
072:
073: private static Map guiTitles;
074:
075: private static Map guiTags;
076:
077: private static Map funcTitles;
078:
079: private static Properties nameMap;
080:
081: private static final Locale TEST_LOCALE = Locale.ENGLISH;
082:
083: public JMeterTest(String name) {
084: super (name);
085: }
086:
087: /*
088: * The suite() method creates separate test suites for each of the types of
089: * test. The suitexxx() methods create a list of items to be tested, and
090: * create a new test instance for each.
091: *
092: * Each test type has its own constructor, which saves the item to be tested
093: *
094: * Note that the suite() method must be static, and the methods to run the
095: * tests must be instance methods so that they can pick up the item value
096: * which was saved by the constructor.
097: *
098: */
099: // Constructor for TestElement tests
100: private TestElement testItem;
101:
102: public JMeterTest(String testName, TestElement te) {
103: super (testName);// Save the method name
104: testItem = te;
105: }
106:
107: // Constructor for Serializable tests
108: private Serializable serObj;
109:
110: public JMeterTest(String testName, Serializable ser) {
111: super (testName);// Save the method name
112: serObj = ser;
113: }
114:
115: // Constructor for GUI tests
116: private JMeterGUIComponent guiItem;
117:
118: public JMeterTest(String testName, JMeterGUIComponent gc) {
119: super (testName);// Save the method name
120: guiItem = gc;
121: }
122:
123: // Constructor for Function tests
124: private Function funcItem;
125:
126: private static boolean classPathShown = false;// Only show classpath once
127:
128: public JMeterTest(String testName, Function fi) {
129: super (testName);// Save the method name
130: funcItem = fi;
131: }
132:
133: /*
134: * Use a suite to allow the tests to be generated at run-time
135: */
136: public static Test suite() throws Exception {
137: // ensure the GuiPackage is initialized.
138: JMeterTreeModel treeModel = new JMeterTreeModel();
139: JMeterTreeListener treeLis = new JMeterTreeListener(treeModel);
140: treeLis.setActionHandler(ActionRouter.getInstance());
141: GuiPackage.getInstance(treeLis, treeModel);
142: try {
143: // The GuiPackage needs a MainFrame to work:
144: org.apache.jmeter.gui.MainFrame main = new org.apache.jmeter.gui.MainFrame(
145: ActionRouter.getInstance(), treeModel, treeLis);
146: } catch (RuntimeException e) {
147: System.out.println("Cannot create MainFrame: " + e);
148: }
149:
150: // The Locale used to instantiate the GUI objects
151: JMeterUtils.setLocale(TEST_LOCALE);
152:
153: TestSuite suite = new TestSuite("JMeterTest");
154: suite.addTest(new JMeterTest("readAliases"));
155: suite.addTest(new JMeterTest("createTitleSet"));
156: suite.addTest(new JMeterTest("createTagSet"));
157: suite.addTest(suiteGUIComponents());
158: suite.addTest(suiteSerializableElements());
159: suite.addTest(suiteTestElements());
160: suite.addTest(suiteBeanComponents());
161: suite.addTest(new JMeterTest("createFunctionSet"));
162: suite.addTest(suiteFunctions());
163: suite.addTest(new JMeterTest("checkGuiSet"));
164: suite.addTest(new JMeterTest("checkFunctionSet"));
165: return suite;
166: }
167:
168: /*
169: * Extract titles from component_reference.xml
170: */
171: public void createTitleSet() throws Exception {
172: guiTitles = new HashMap(90);
173:
174: String compref = "../xdocs/usermanual/component_reference.xml";
175: SAXBuilder bldr = new SAXBuilder();
176: Document doc;
177: doc = bldr.build(compref);
178: Element root = doc.getRootElement();
179: Element body = root.getChild("body");
180: List sections = body.getChildren("section");
181: for (int i = 0; i < sections.size(); i++) {
182: List components = ((Element) sections.get(i))
183: .getChildren("component");
184: for (int j = 0; j < components.size(); j++) {
185: Element comp = (Element) components.get(j);
186: String nm = comp.getAttributeValue("name");
187: if (!nm.equals("SSL Manager")) {// Not a true GUI component
188: guiTitles.put(nm.replace(' ', '_'), Boolean.FALSE);
189: }
190: }
191: }
192: // Add titles that don't need to be documented
193: //guiTitles.put("Root", Boolean.FALSE);
194: guiTitles.put("Example Sampler", Boolean.FALSE);
195: }
196:
197: /*
198: * Extract titles from component_reference.xml
199: */
200: public void createTagSet() throws Exception {
201: guiTags = new HashMap(90);
202:
203: String compref = "../xdocs/usermanual/component_reference.xml";
204: SAXBuilder bldr = new SAXBuilder();
205: Document doc;
206: doc = bldr.build(compref);
207: Element root = doc.getRootElement();
208: Element body = root.getChild("body");
209: List sections = body.getChildren("section");
210: for (int i = 0; i < sections.size(); i++) {
211: List components = ((Element) sections.get(i))
212: .getChildren("component");
213: for (int j = 0; j < components.size(); j++) {
214: Element comp = (Element) components.get(j);
215: guiTags.put(comp.getAttributeValue("tag"),
216: Boolean.FALSE);
217: }
218: }
219: }
220:
221: /*
222: * Extract titles from functions.xml
223: */
224: public void createFunctionSet() throws Exception {
225: funcTitles = new HashMap(20);
226:
227: String compref = "../xdocs/usermanual/functions.xml";
228: SAXBuilder bldr = new SAXBuilder();
229: Document doc;
230: doc = bldr.build(compref);
231: Element root = doc.getRootElement();
232: Element body = root.getChild("body");
233: Element section = body.getChild("section");
234: List sections = section.getChildren("subsection");
235: for (int i = 0; i < sections.size(); i++) {
236: List components = ((Element) sections.get(i))
237: .getChildren("component");
238: for (int j = 0; j < components.size(); j++) {
239: Element comp = (Element) components.get(j);
240: funcTitles.put(comp.getAttributeValue("name"),
241: Boolean.FALSE);
242: }
243: }
244: }
245:
246: private int scanprintMap(Map m, String t) {
247: Set s = m.keySet();
248: int unseen = 0;
249: if (s.size() == 0)
250: return 0;
251: Iterator i = s.iterator();
252: while (i.hasNext()) {
253: Object key = i.next();
254: if (!m.get(key).equals(Boolean.TRUE)) {
255: if (unseen == 0)// first time
256: {
257: System.out.println("\nNames remaining in " + t
258: + " Map:");
259: }
260: unseen++;
261: System.out.println(key);
262: }
263: }
264: return unseen;
265: }
266:
267: public void checkGuiSet() throws Exception {
268: guiTitles.remove("Example Sampler");// We don't mind if this is left over
269: guiTitles.remove("Sample_Result_Save_Configuration");// Ditto, not a sampler
270: assertEquals("Should not have any names left over", 0,
271: scanprintMap(guiTitles, "GUI"));
272: }
273:
274: public void checkFunctionSet() throws Exception {
275: assertEquals("Should not have any names left over", 0,
276: scanprintMap(funcTitles, "Function"));
277: }
278:
279: /*
280: * Test GUI elements - create the suite of tests
281: */
282: private static Test suiteGUIComponents() throws Exception {
283: TestSuite suite = new TestSuite("GuiComponents");
284: Iterator iter = getObjects(JMeterGUIComponent.class).iterator();
285: while (iter.hasNext()) {
286: JMeterGUIComponent item = (JMeterGUIComponent) iter.next();
287: if (item instanceof JMeterTreeNode) {
288: System.out
289: .println("INFO: JMeterGUIComponent: skipping all tests "
290: + item.getClass().getName());
291: continue;
292: }
293: if (item instanceof ObsoleteGui) {
294: continue;
295: }
296: TestSuite ts = new TestSuite(item.getClass().getName());
297: ts.addTest(new JMeterTest("GUIComponents1", item));
298: if (item instanceof TestBeanGUI) {
299: System.out
300: .println("INFO: JMeterGUIComponent: skipping some tests "
301: + item.getClass().getName());
302: } else {
303: ts.addTest(new JMeterTest("GUIComponents2", item));
304: ts.addTest(new JMeterTest("runGUITitle", item));
305: }
306: suite.addTest(ts);
307: }
308: return suite;
309: }
310:
311: /*
312: * Test Functions - create the suite of tests
313: */
314: private static Test suiteFunctions() throws Exception {
315: TestSuite suite = new TestSuite("Functions");
316: Iterator iter = getObjects(Function.class).iterator();
317: while (iter.hasNext()) {
318: Object item = iter.next();
319: if (item.getClass().equals(CompoundVariable.class)) {
320: continue;
321: }
322: TestSuite ts = new TestSuite(item.getClass().getName());
323: ts.addTest(new JMeterTest("runFunction", (Function) item));
324: ts.addTest(new JMeterTest("runFunction2", (Function) item));
325: suite.addTest(ts);
326: }
327: return suite;
328: }
329:
330: /*
331: * Test GUI elements - create the suite of tests
332: */
333: private static Test suiteBeanComponents() throws Exception {
334: TestSuite suite = new TestSuite("BeanComponents");
335: Iterator iter = getObjects(TestBean.class).iterator();
336: while (iter.hasNext()) {
337: Class c = iter.next().getClass();
338: try {
339: JMeterGUIComponent item = new TestBeanGUI(c);
340: // JMeterGUIComponent item = (JMeterGUIComponent) iter.next();
341: TestSuite ts = new TestSuite(item.getClass().getName());
342: ts.addTest(new JMeterTest("GUIComponents2", item));
343: ts.addTest(new JMeterTest("runGUITitle", item));
344: suite.addTest(ts);
345: } catch (IllegalArgumentException e) {
346: System.out.println("Cannot create test for "
347: + c.getName() + " " + e);
348: e.printStackTrace(System.out);
349: }
350: }
351: return suite;
352: }
353:
354: /*
355: * Test GUI elements - run the test
356: */
357: public void runGUITitle() throws Exception {
358: if (guiTitles.size() > 0) {
359: String title = guiItem.getDocAnchor();
360: boolean ct = guiTitles.containsKey(title);
361: if (ct) {
362: guiTitles.put(title, Boolean.TRUE);// So we can detect extra entries
363: }
364: String name = guiItem.getClass().getName();
365: if (// Is this a work in progress or an internal GUI component?
366: (title != null && title.length() > 0) // Will be "" for internal components
367: && (title.toUpperCase().indexOf("(ALPHA") == -1)
368: && (title.toUpperCase().indexOf("(BETA") == -1)
369: && (!title.equals("Example1")) // Skip the example samplers ...
370: && (!title.equals("Example2"))
371: && (!name.startsWith("org.apache.jmeter.examples."))) {// No, not a work in progress ...
372: String s = "component_reference.xml needs '" + title
373: + "' anchor for " + name;
374: if (!ct) {
375: log.warn(s); // Record in log as well
376: }
377: assertTrue(s, ct);
378: }
379: }
380: }
381:
382: /*
383: * run the function test
384: */
385: public void runFunction() throws Exception {
386: if (funcTitles.size() > 0) {
387: String title = funcItem.getReferenceKey();
388: boolean ct = funcTitles.containsKey(title);
389: if (ct)
390: funcTitles.put(title, Boolean.TRUE);// For detecting extra
391: // entries
392: if (// Is this a work in progress ?
393: title.indexOf("(ALPHA") == -1
394: && title.indexOf("(EXPERIMENTAL") == -1) {// No,
395: // not
396: // a
397: // work
398: // in
399: // progress
400: // ...
401: String s = "function.xml needs '" + title
402: + "' entry for "
403: + funcItem.getClass().getName();
404: if (!ct)
405: log.warn(s); // Record in log as well
406: assertTrue(s, ct);
407: }
408: }
409: }
410:
411: /*
412: * Check that function descriptions are OK
413: */
414: public void runFunction2() throws Exception {
415: Iterator i = funcItem.getArgumentDesc().iterator();
416: while (i.hasNext()) {
417: Object o = i.next();
418: assertTrue("Description must be a String",
419: o instanceof String);
420: assertFalse("Description must not start with [refkey",
421: ((String) o).startsWith("[refkey"));
422: }
423: }
424:
425: /*
426: * Test GUI elements - run for all components
427: */
428: public void GUIComponents1() throws Exception {
429: // We must set the Locale to the same value that was used when the
430: // GUI objects was instantiated in this class
431: JMeterUtils.setLocale(TEST_LOCALE);
432: String name = guiItem.getClass().getName();
433:
434: assertEquals("Name should be same as static label for " + name,
435: guiItem.getStaticLabel(), guiItem.getName());
436: if (name.startsWith("org.apache.jmeter.examples.")) {
437: return;
438: }
439: if (!name.endsWith("TestBeanGUI")) {
440: try {
441: String label = guiItem.getLabelResource();
442: assertTrue(label.length() > 0);
443: if (!label.equals("unused")) { // TODO use constant
444: assertFalse("'" + label
445: + "' should be in resource file for "
446: + name, JMeterUtils.getResString(label)
447: .startsWith(JMeterUtils.RES_KEY_PFX));
448: }
449: } catch (UnsupportedOperationException uoe) {
450: log
451: .warn("Class has not yet implemented getLabelResource "
452: + name);
453: }
454: }
455: checkElementAlias(guiItem);
456: }
457:
458: /*
459: * Test GUI elements - not run for TestBeanGui items
460: */
461: public void GUIComponents2() throws Exception {
462: String name = guiItem.getClass().getName();
463:
464: // TODO these assertions should be separate tests
465:
466: TestElement el = guiItem.createTestElement();
467: assertNotNull(name + ".createTestElement should be non-null ",
468: el);
469: assertEquals("GUI-CLASS: Failed on " + name, name, el
470: .getPropertyAsString(TestElement.GUI_CLASS));
471:
472: assertEquals("NAME: Failed on " + name, guiItem.getName(), el
473: .getPropertyAsString(TestElement.NAME));
474: assertEquals("TEST-CLASS: Failed on " + name, el.getClass()
475: .getName(), el
476: .getPropertyAsString(TestElement.TEST_CLASS));
477: TestElement el2 = guiItem.createTestElement();
478: el.setProperty(TestElement.NAME, "hey, new name!:");
479: el.setProperty("NOT", "Shouldn't be here");
480: if (!(guiItem instanceof UnsharedComponent)) {
481: assertEquals("SHARED: Failed on " + name, "", el2
482: .getPropertyAsString("NOT"));
483: }
484: log.debug("Saving element: " + el.getClass());
485: ByteArrayOutputStream bos = new ByteArrayOutputStream();
486: SaveService.saveElement(el, bos);
487: ByteArrayInputStream bis = new ByteArrayInputStream(bos
488: .toByteArray());
489: bos.close();
490: el = (TestElement) SaveService.loadElement(bis);
491: bis.close();
492: assertNotNull("Load element failed on: " + name, el);
493: guiItem.configure(el);
494: assertEquals("CONFIGURE-TEST: Failed on " + name, el
495: .getPropertyAsString(TestElement.NAME), guiItem
496: .getName());
497: guiItem.modifyTestElement(el2);
498: assertEquals("Modify Test: Failed on " + name,
499: "hey, new name!:", el2
500: .getPropertyAsString(TestElement.NAME));
501: }
502:
503: /*
504: * Test serializable elements - create the suite of tests
505: */
506: private static Test suiteSerializableElements() throws Exception {
507: TestSuite suite = new TestSuite("SerializableElements");
508: Iterator iter = getObjects(Serializable.class).iterator();
509: while (iter.hasNext()) {
510: Serializable serObj = (Serializable) iter.next();
511: if (serObj.getClass().getName().endsWith("_Stub")) {
512: continue;
513: }
514: TestSuite ts = new TestSuite(serObj.getClass().getName());
515: ts.addTest(new JMeterTest("runSerialTest", serObj));
516: suite.addTest(ts);
517: }
518: return suite;
519: }
520:
521: /*
522: * Test serializable elements - test the object
523: */
524: public void runSerialTest() throws Exception {
525: if (!(serObj instanceof JComponent)) {
526: try {
527: ByteArrayOutputStream bytes = new ByteArrayOutputStream();
528: ObjectOutputStream out = new ObjectOutputStream(bytes);
529: out.writeObject(serObj);
530: out.close();
531: ObjectInputStream in = new ObjectInputStream(
532: new ByteArrayInputStream(bytes.toByteArray()));
533: Object readObject = in.readObject();
534: in.close();
535: assertEquals("deserializing class: "
536: + serObj.getClass().getName(), serObj
537: .getClass(), readObject.getClass());
538: } catch (Throwable e) {
539: fail("serialization of " + serObj.getClass().getName()
540: + " failed: " + e);
541: }
542: }
543: }
544:
545: /*
546: * Test TestElements - create the suite
547: */
548: private static Test suiteTestElements() throws Exception {
549: TestSuite suite = new TestSuite("TestElements");
550: Iterator iter = getObjects(TestElement.class).iterator();
551: while (iter.hasNext()) {
552: TestElement item = (TestElement) iter.next();
553: TestSuite ts = new TestSuite(item.getClass().getName());
554: ts.addTest(new JMeterTest("runTestElement", item));
555: suite.addTest(ts);
556: }
557: return suite;
558: }
559:
560: /*
561: * Test TestElements - implement the test case
562: */
563: public void runTestElement() throws Exception {
564: checkElementCloning(testItem);
565: String name = testItem.getClass().getName();
566: assertTrue(name + " must implement Serializable",
567: testItem instanceof Serializable);
568: if (name.startsWith("org.apache.jmeter.examples.")) {
569: return;
570: }
571: if (name.equals("org.apache.jmeter.control.TransactionSampler")) {
572: return; // Not a real sampler
573: }
574:
575: checkElementAlias(testItem);
576: }
577:
578: public void readAliases() throws Exception {
579: nameMap = SaveService.loadProperties();
580: assertNotNull("SaveService nameMap should not be null", nameMap);
581: }
582:
583: private void checkElementAlias(Object item) {
584: String name = item.getClass().getName();
585: boolean contains = nameMap.values().contains(name);
586: if (!contains) {
587: //System.out.println(name.substring(name.lastIndexOf('.')+1)+"="+name);
588: fail("SaveService nameMap should contain " + name);
589: }
590: }
591:
592: private static Collection getObjects(Class extendsClass)
593: throws Exception {
594: String exName = extendsClass.getName();
595: Object myThis = "";
596: Iterator classes = ClassFinder.findClassesThatExtend(
597: JMeterUtils.getSearchPaths(),
598: new Class[] { extendsClass }).iterator();
599: List objects = new LinkedList();
600: String n = "";
601: boolean caughtError = true;
602: Throwable caught = null;
603: try {
604: while (classes.hasNext()) {
605: n = (String) classes.next();
606: // TODO - improve this check
607: if (n.endsWith("RemoteJMeterEngineImpl")) {
608: continue; // Don't try to instantiate remote server
609: }
610: Class c = null;
611: try {
612: c = Class.forName(n);
613: try {
614: // Try with a parameter-less constructor first
615: objects.add(c.newInstance());
616: } catch (InstantiationException e) {
617: caught = e;
618: // System.out.println(e.toString());
619: try {
620: // Events often have this constructor
621: objects.add(c.getConstructor(
622: new Class[] { Object.class })
623: .newInstance(
624: new Object[] { myThis }));
625: } catch (NoSuchMethodException f) {
626: // no luck. Ignore this class
627: System.out.println("WARN: " + exName
628: + ": NoSuchMethodException " + n);
629: }
630: }
631: } catch (NoClassDefFoundError e) {
632: // no luck. Ignore this class
633: System.out.println("WARN: " + exName
634: + ": NoClassDefFoundError " + n);
635: } catch (IllegalAccessException e) {
636: caught = e;
637: System.out.println("WARN: " + exName
638: + ": IllegalAccessException " + n);
639: // We won't test restricted-access classes.
640: }
641: // JDK1.4: catch (java.awt.HeadlessException e)
642: // JDK1.4: {
643: // JDK1.4: System.out.println("Error creating "+n+"
644: // "+e.toString());
645: // JDK1.4: }
646: catch (Exception e) {
647: caught = e;
648: if ((e instanceof RemoteException)
649: || e.getClass().getName().equals(
650: "java.awt.HeadlessException")// for
651: // JDK1.3
652: ) {
653: System.out.println("WARN: " + "Error creating "
654: + n + " " + e.toString());
655: } else {
656: throw new Exception("Error creating " + n + " "
657: + e.toString());
658: }
659: }
660: }
661: caughtError = false;
662: } finally {
663: if (caughtError) {
664: System.out.println("Last class=" + n);
665: System.out.println("objects.size=" + objects.size());
666: System.out.println("Last error=" + caught);
667: }
668: }
669:
670: if (objects.size() == 0) {
671: System.out.println("No classes found that extend " + exName
672: + ". Check the following:");
673: System.out.println("Search paths are:");
674: String ss[] = JMeterUtils.getSearchPaths();
675: for (int i = 0; i < ss.length; i++) {
676: System.out.println(ss[i]);
677: }
678: if (!classPathShown) {// Only dump it once
679: System.out.println("Class path is:");
680: String cp = System.getProperty("java.class.path");
681: String cpe[] = JOrphanUtils.split(cp,
682: java.io.File.pathSeparator);
683: for (int i = 0; i < cpe.length; i++) {
684: System.out.println(cpe[i]);
685: }
686: classPathShown = true;
687: }
688: }
689: return objects;
690: }
691:
692: private static void cloneTesting(TestElement item,
693: TestElement clonedItem) {
694: assertTrue(item != clonedItem);
695: assertEquals("CLONE-SAME-CLASS: testing "
696: + item.getClass().getName(), item.getClass().getName(),
697: clonedItem.getClass().getName());
698: }
699:
700: private static void checkElementCloning(TestElement item) {
701: TestElement clonedItem = (TestElement) item.clone();
702: cloneTesting(item, clonedItem);
703: PropertyIterator iter2 = item.propertyIterator();
704: while (iter2.hasNext()) {
705: JMeterProperty item2 = iter2.next();
706: // [sebb] assertEquals(item2,
707: // clonedItem.getProperty(item2.getName()));
708: assertEquals(item2.getStringValue(), clonedItem
709: .getProperty(item2.getName()).getStringValue());
710: assertTrue(item2 != clonedItem.getProperty(item2.getName()));
711: }
712: }
713: }
|