Index: C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/test/src/org/apache/jmeter/samplers/TestSampleSaveConfiguration.java =================================================================== --- C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/test/src/org/apache/jmeter/samplers/TestSampleSaveConfiguration.java (revision 0) +++ C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/test/src/org/apache/jmeter/samplers/TestSampleSaveConfiguration.java (revision 0) @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.jmeter.samplers; + +import junit.framework.TestCase; + +public class TestSampleSaveConfiguration extends TestCase { + public TestSampleSaveConfiguration(String name) { + super(name); + } + + public void testClone() throws Exception { + SampleSaveConfiguration a = new SampleSaveConfiguration(); + a.setUrl(false); + a.setAssertions(true); + a.setDefaultDelimiter(); + a.setDefaultTimeStampFormat(); + a.setDataType(true); + assertFalse(a.saveUrl()); + assertNotNull(a.getDelimiter()); + assertTrue(a.saveAssertions()); + assertTrue(a.saveDataType()); + + // Original and clone should be equal + SampleSaveConfiguration cloneA = (SampleSaveConfiguration) a.clone(); + assertNotSame(a, cloneA); + assertEquals(a, cloneA); + assertTrue(a.equals(cloneA)); + assertTrue(cloneA.equals(a)); + assertEquals(a.hashCode(), cloneA.hashCode()); + + // Change the original + a.setUrl(true); + assertFalse(a.equals(cloneA)); + assertFalse(cloneA.equals(a)); + assertFalse(a.hashCode() == cloneA.hashCode()); + + // Change the original back again + a.setUrl(false); + assertEquals(a, cloneA); + assertTrue(a.equals(cloneA)); + assertTrue(cloneA.equals(a)); + assertEquals(a.hashCode(), cloneA.hashCode()); + } + + public void testEqualsAndHashCode() throws Exception { + SampleSaveConfiguration a = new SampleSaveConfiguration(); + a.setUrl(false); + a.setAssertions(true); + a.setDefaultDelimiter(); + a.setDefaultTimeStampFormat(); + a.setDataType(true); + SampleSaveConfiguration b = new SampleSaveConfiguration(); + b.setUrl(false); + b.setAssertions(true); + b.setDefaultDelimiter(); + b.setDefaultTimeStampFormat(); + b.setDataType(true); + + // a and b should be equal + assertEquals(a, b); + assertTrue(a.equals(b)); + assertTrue(b.equals(a)); + assertEquals(a.hashCode(), b.hashCode()); + assertEquals(a.saveUrl(), b.saveUrl()); + assertEquals(a.saveAssertions(), b.saveAssertions()); + assertEquals(a.getDelimiter(), b.getDelimiter()); + assertEquals(a.saveDataType(), b.saveDataType()); + + a.setAssertions(false); + // a and b should not be equal + assertFalse(a.equals(b)); + assertFalse(b.equals(a)); + assertFalse(a.hashCode() == b.hashCode()); + assertFalse(a.saveAssertions() == b.saveAssertions()); + } +} + Index: C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/core/org/apache/jmeter/samplers/SampleSaveConfiguration.java =================================================================== --- C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/core/org/apache/jmeter/samplers/SampleSaveConfiguration.java (revision 536456) +++ C:/Documents and Settings/alf.hogemark/workspace/Jmeter 2.2 official/src/core/org/apache/jmeter/samplers/SampleSaveConfiguration.java (working copy) @@ -195,7 +195,7 @@ private static final String SAVE_THREAD_COUNTS = "jmeter.save.saveservice.thread_counts"; // $NON_NLS-1$ - // N.B. Remember to update the clone method when adding new variables. + // N.B. Remember to update the equals and hashCode methods when adding new variables. // Initialise values from properties private boolean time = _time, latency = _latency, timestamp = _timestamp, success = _success, label = _label, @@ -362,37 +362,100 @@ // } public Object clone() { - SampleSaveConfiguration s = new SampleSaveConfiguration(); - s.time = time; - s.latency = latency; - s.timestamp = timestamp; - s.success = success; - s.label = label; - s.code = code; - s.message = message; - s.threadName = threadName; - s.dataType = dataType; - s.encoding = encoding; - s.assertions = assertions; - s.subresults = subresults; - s.responseData = responseData; - s.samplerData = samplerData; - s.xml = xml; - s.fieldNames = fieldNames; - s.responseHeaders = responseHeaders; - s.requestHeaders = requestHeaders; - s.formatter = formatter; - s.assertionsResultsToSave = assertionsResultsToSave; - s.saveAssertionResultsFailureMessage = saveAssertionResultsFailureMessage; - s.delimiter = delimiter; - s.printMilliseconds = printMilliseconds; - s.responseDataOnError = responseDataOnError; - s.url = url; - s.bytes = bytes; - s.fileName = fileName; - s.threadCounts = threadCounts; - return s; + try { + SampleSaveConfiguration clone = (SampleSaveConfiguration)super.clone(); + if(this.formatter != null) { + clone.formatter = (SimpleDateFormat)this.formatter.clone(); + } + return clone; + } + catch(CloneNotSupportedException e) { + // this should not happen + return null; + } } + + public boolean equals(Object obj) { + if(this == obj) { + return true; + } + if((obj == null) || (obj.getClass() != this.getClass())) { + return false; + } + // We know we are comparing to another SampleSaveConfiguration + SampleSaveConfiguration s = (SampleSaveConfiguration)obj; + boolean primitiveValues = s.time == time && + s.latency == latency && + s.timestamp == timestamp && + s.success == success && + s.label == label && + s.code == code && + s.message == message && + s.threadName == threadName && + s.dataType == dataType && + s.encoding == encoding && + s.assertions == assertions && + s.subresults == subresults && + s.responseData == responseData && + s.samplerData == samplerData && + s.xml == xml && + s.fieldNames == fieldNames && + s.responseHeaders == responseHeaders && + s.requestHeaders == requestHeaders && + s.assertionsResultsToSave == assertionsResultsToSave && + s.saveAssertionResultsFailureMessage == saveAssertionResultsFailureMessage && + s.printMilliseconds == printMilliseconds && + s.responseDataOnError == responseDataOnError && + s.url == url && + s.bytes == bytes && + s.fileName == fileName && + s.threadCounts == threadCounts; + + boolean stringValues = false; + if(primitiveValues) { + stringValues = s.delimiter == delimiter || (delimiter != null && delimiter.equals(s.delimiter)); + } + boolean complexValues = false; + if(primitiveValues && stringValues) { + complexValues = s.formatter == formatter || (formatter != null && formatter.equals(s.formatter)); + } + + return primitiveValues && stringValues && complexValues; + } + + public int hashCode() { + int hash = 7; + hash = 31 * hash + (time ? 1 : 0); + hash = 31 * hash + (latency ? 1 : 0); + hash = 31 * hash + (timestamp ? 1 : 0); + hash = 31 * hash + (success ? 1 : 0); + hash = 31 * hash + (label ? 1 : 0); + hash = 31 * hash + (code ? 1 : 0); + hash = 31 * hash + (message ? 1 : 0); + hash = 31 * hash + (threadName ? 1 : 0); + hash = 31 * hash + (dataType ? 1 : 0); + hash = 31 * hash + (encoding ? 1 : 0); + hash = 31 * hash + (assertions ? 1 : 0); + hash = 31 * hash + (subresults ? 1 : 0); + hash = 31 * hash + (responseData ? 1 : 0); + hash = 31 * hash + (samplerData ? 1 : 0); + hash = 31 * hash + (xml ? 1 : 0); + hash = 31 * hash + (fieldNames ? 1 : 0); + hash = 31 * hash + (responseHeaders ? 1 : 0); + hash = 31 * hash + (requestHeaders ? 1 : 0); + hash = 31 * hash + assertionsResultsToSave; + hash = 31 * hash + (saveAssertionResultsFailureMessage ? 1 : 0); + hash = 31 * hash + (printMilliseconds ? 1 : 0); + hash = 31 * hash + (responseDataOnError ? 1 : 0); + hash = 31 * hash + (url ? 1 : 0); + hash = 31 * hash + (bytes ? 1 : 0); + hash = 31 * hash + (fileName ? 1 : 0); + hash = 31 * hash + (threadCounts ? 1 : 0); + hash = 31 * hash + (delimiter != null ? delimiter.hashCode() : 0); + hash = 31 * hash + (formatter != null ? formatter.hashCode() : 0); + + return hash; + } ///////////////////// Start of standard save/set access methods /////////////////////