Skip to content

Commit 15ff926

Browse files
authored
Remove the optimization which data provider is remembered in a multiplication (#2119)
This could cause unintuitive behavior and changes in test sets that are executed.
1 parent eee078a commit 15ff926

File tree

4 files changed

+33
-87
lines changed

4 files changed

+33
-87
lines changed

spock-core/src/main/java/org/spockframework/runtime/DataIteratorFactory.java

Lines changed: 21 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -702,16 +702,6 @@ private static class DataProviderMultiplier extends BaseDataIterator {
702702
*/
703703
private final Object[] multiplierProviders;
704704

705-
/**
706-
* The data provider multiplier that is used as multiplicand
707-
* in this multiplication, if it represents in an
708-
* {@code (a * (b * c))} multiplication the {@code (a * bc)} part
709-
* or otherwise {@code null}.
710-
* Outside the constructor it is only used as condition
711-
* and for the final cleanup,
712-
*/
713-
private final DataProviderMultiplier multiplicandProvider;
714-
715705
/**
716706
* The data providers that are used as multiplicand
717707
* in this multiplication, if it represents in an
@@ -739,12 +729,6 @@ private static class DataProviderMultiplier extends BaseDataIterator {
739729
*/
740730
private final Iterator<?>[] multiplicandIterators;
741731

742-
/**
743-
* A flag that remembers whether the factors were swapped for optimization, so that the result values can be
744-
* swapped back for expected, consistent, and reproducible results.
745-
*/
746-
private boolean factorsSwapped = false;
747-
748732
/**
749733
* The current set of multiplier values that is combined with each set of multiplicand values,
750734
* before the next multiplier value is calculated.
@@ -794,8 +778,15 @@ public DataProviderMultiplier(IRunSupervisor supervisor, SpockExecutionContext c
794778
Object[] multiplierProviders, Object[] multiplicandProviders) {
795779
super(supervisor, context);
796780
this.dataVariableNames = Objects.requireNonNull(dataVariableNames);
781+
this.multiplierProviderInfos = multiplierProviderInfos;
782+
this.multiplicandProviderInfos = multiplicandProviderInfos;
797783
multiplierProvider = null;
798-
multiplicandProvider = null;
784+
this.multiplierProviders = multiplierProviders;
785+
this.multiplicandProviders = multiplicandProviders;
786+
787+
collectedMultiplicandValues = createMultiplicandStorage();
788+
multiplierIterators = createIterators(this.multiplierProviders, this.multiplierProviderInfos);
789+
multiplicandIterators = createIterators(this.multiplicandProviders, this.multiplicandProviderInfos);
799790

800791
int estimatedMultiplierIterations = estimateNumIterations(Objects.requireNonNull(multiplierProviders));
801792
int estimatedMultiplicandIterations = estimateNumIterations(Objects.requireNonNull(multiplicandProviders));
@@ -805,26 +796,6 @@ public DataProviderMultiplier(IRunSupervisor supervisor, SpockExecutionContext c
805796
: estimatedMultiplierIterations * estimatedMultiplicandIterations;
806797

807798
processedDataProviders = multiplierProviders.length + multiplicandProviders.length;
808-
809-
if ((estimatedMultiplierIterations != UNKNOWN_ITERATIONS)
810-
&& ((estimatedMultiplicandIterations == UNKNOWN_ITERATIONS) || (estimatedMultiplicandIterations > estimatedMultiplierIterations))) {
811-
// multiplier is not unknown and multiplicand is unknown or larger,
812-
// swap factors so that potentially fewer values need to be remembered in memory
813-
factorsSwapped = true;
814-
this.multiplierProviderInfos = multiplicandProviderInfos;
815-
this.multiplicandProviderInfos = multiplierProviderInfos;
816-
this.multiplierProviders = multiplicandProviders;
817-
this.multiplicandProviders = multiplierProviders;
818-
} else {
819-
this.multiplierProviderInfos = multiplierProviderInfos;
820-
this.multiplicandProviderInfos = multiplicandProviderInfos;
821-
this.multiplierProviders = multiplierProviders;
822-
this.multiplicandProviders = multiplicandProviders;
823-
}
824-
825-
collectedMultiplicandValues = createMultiplicandStorage();
826-
multiplierIterators = createIterators(this.multiplierProviders, this.multiplierProviderInfos);
827-
multiplicandIterators = createIterators(this.multiplicandProviders, this.multiplicandProviderInfos);
828799
}
829800

830801
/**
@@ -845,6 +816,15 @@ public DataProviderMultiplier(IRunSupervisor supervisor, SpockExecutionContext c
845816
DataProviderMultiplier multiplierProvider, Object[] multiplicandProviders) {
846817
super(supervisor, context);
847818
this.dataVariableNames = Objects.requireNonNull(dataVariableNames);
819+
multiplierProviderInfos = null;
820+
this.multiplicandProviderInfos = multiplicandProviderInfos;
821+
this.multiplierProvider = multiplierProvider;
822+
multiplierProviders = null;
823+
this.multiplicandProviders = multiplicandProviders;
824+
825+
collectedMultiplicandValues = createMultiplicandStorage();
826+
multiplierIterators = new Iterator[]{multiplierProvider};
827+
multiplicandIterators = createIterators(this.multiplicandProviders, this.multiplicandProviderInfos);
848828

849829
int estimatedMultiplierIterations = Objects.requireNonNull(multiplierProvider).getEstimatedNumIterations();
850830
int estimatedMultiplicandIterations = estimateNumIterations(Objects.requireNonNull(multiplicandProviders));
@@ -854,32 +834,6 @@ public DataProviderMultiplier(IRunSupervisor supervisor, SpockExecutionContext c
854834
: estimatedMultiplierIterations * estimatedMultiplicandIterations;
855835

856836
processedDataProviders = multiplierProvider.getProcessedDataProviders() + multiplicandProviders.length;
857-
858-
if ((estimatedMultiplierIterations != UNKNOWN_ITERATIONS)
859-
&& ((estimatedMultiplicandIterations == UNKNOWN_ITERATIONS) || (estimatedMultiplicandIterations > estimatedMultiplierIterations))) {
860-
// multiplier is not unknown and multiplicand is unknown or larger,
861-
// swap factors so that potentially fewer values need to be remembered in memory
862-
factorsSwapped = true;
863-
multiplierProviderInfos = multiplicandProviderInfos;
864-
this.multiplicandProviderInfos = null;
865-
this.multiplierProvider = null;
866-
multiplierProviders = multiplicandProviders;
867-
multiplicandProvider = multiplierProvider;
868-
this.multiplicandProviders = null;
869-
collectedMultiplicandValues = singletonList(new ArrayList<>());
870-
multiplierIterators = createIterators(multiplierProviders, multiplierProviderInfos);
871-
multiplicandIterators = new Iterator[]{multiplierProvider};
872-
} else {
873-
multiplierProviderInfos = null;
874-
this.multiplicandProviderInfos = multiplicandProviderInfos;
875-
this.multiplierProvider = multiplierProvider;
876-
multiplierProviders = null;
877-
multiplicandProvider = null;
878-
this.multiplicandProviders = multiplicandProviders;
879-
collectedMultiplicandValues = createMultiplicandStorage();
880-
multiplierIterators = new Iterator[]{multiplierProvider};
881-
multiplicandIterators = createIterators(this.multiplicandProviders, this.multiplicandProviderInfos);
882-
}
883837
}
884838

885839
private List<List<Object>> createMultiplicandStorage() {
@@ -892,7 +846,7 @@ private List<List<Object>> createMultiplicandStorage() {
892846

893847
@Override
894848
public void close() throws Exception {
895-
closeQuietly(multiplierProvider, multiplicandProvider);
849+
closeQuietly(multiplierProvider);
896850
closeQuietly(multiplierProviders);
897851
closeQuietly(multiplicandProviders);
898852
}
@@ -958,21 +912,11 @@ public Object[] next() {
958912
collectedMultiplicandValues.get(i).add(nextMultiplicandValues[i]);
959913
}
960914
}
961-
if (multiplicandProvider != null) {
962-
nextMultiplicandValues = ((Object[]) nextMultiplicandValues[0]);
963-
}
964915

965916
// prepare result
966-
Object[] nextMultiplierValues;
967-
if (factorsSwapped) {
968-
nextMultiplierValues = nextMultiplicandValues;
969-
nextMultiplicandValues = currentMultiplierValues;
970-
} else {
971-
nextMultiplierValues = currentMultiplierValues;
972-
}
973-
Object[] next = new Object[nextMultiplierValues.length + nextMultiplicandValues.length];
974-
System.arraycopy(nextMultiplierValues, 0, next, 0, nextMultiplierValues.length);
975-
System.arraycopy(nextMultiplicandValues, 0, next, nextMultiplierValues.length, nextMultiplicandValues.length);
917+
Object[] next = new Object[currentMultiplierValues.length + nextMultiplicandValues.length];
918+
System.arraycopy(currentMultiplierValues, 0, next, 0, currentMultiplierValues.length);
919+
System.arraycopy(nextMultiplicandValues, 0, next, currentMultiplierValues.length, nextMultiplicandValues.length);
976920
return next;
977921
}
978922

spock-specs/src/test/groovy/org/spockframework/docs/datadriven/DataSpec.groovy

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,10 @@ class DataSpec extends EmbeddedSpecification {
200200
tag::single-data-providers-combined-result1[]
201201
- `feature [a: 1, b: 5, c: 7, #0]`
202202
- `feature [a: 2, b: 5, c: 8, #1]`
203-
- `feature [a: 3, b: 6, c: 7, #2]`
204-
- `feature [a: 4, b: 6, c: 8, #3]`
203+
- `feature [a: 3, b: 5, c: 9, #2]`
204+
- `feature [a: 4, b: 6, c: 7, #3]`
205+
- `feature [a: 5, b: 6, c: 8, #4]`
206+
- `feature [a: 6, b: 6, c: 9, #5]`
205207
end::single-data-providers-combined-result1[]
206208
'''
207209
.stripIndent(*(GroovyRuntimeUtil.groovy3orNewer ? [true] : []))
@@ -218,10 +220,10 @@ class DataSpec extends EmbeddedSpecification {
218220
219221
// tag::single-data-providers-combined1[]
220222
where:
221-
a << [1, 2, 3, 4]
223+
a << [1, 2, 3, 4, 5, 6]
222224
b << [5, 6]
223225
combined:
224-
c << [7, 8]
226+
c << [7, 8, 9]
225227
// end::single-data-providers-combined1[]
226228
}
227229
'''

spock-specs/src/test/groovy/org/spockframework/smoke/parameterization/DataTables.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,10 @@ class DataTables extends EmbeddedSpecification {
316316
results.testEvents().started().list().testDescriptor.displayName == [
317317
'a feature (#a #b #c)',
318318
'a feature (1 3 4)',
319-
'a feature (2 3 4)',
320319
'a feature (1 3 5)',
321-
'a feature (2 3 5)',
322320
'a feature (1 3 6)',
321+
'a feature (2 3 4)',
322+
'a feature (2 3 5)',
323323
'a feature (2 3 6)'
324324
]
325325

spock-specs/src/test/resources/snapshots/org/spockframework/smoke/parameterization/DataTables/filtered_iterations_are_logged.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Filtered iteration [i: 2, a: 2, b: 2, c: 1]:
1+
Filtered iteration [i: 2, a: 1, b: 1, c: 2]:
22
Condition not satisfied:
33

44
i == 1
@@ -7,7 +7,7 @@ i == 1
77

88
at apackage.ASpec.a feature(script.groovy:15)
99

10-
Filtered iteration [i: 3, a: 1, b: 1, c: 2]:
10+
Filtered iteration [i: 3, a: 1, b: 1, c: 3]:
1111
Condition not satisfied:
1212

1313
i == 1
@@ -16,7 +16,7 @@ i == 1
1616

1717
at apackage.ASpec.a feature(script.groovy:15)
1818

19-
Filtered iteration [i: 4, a: 2, b: 2, c: 2]:
19+
Filtered iteration [i: 4, a: 2, b: 2, c: 1]:
2020
Condition not satisfied:
2121

2222
i == 1
@@ -25,7 +25,7 @@ i == 1
2525

2626
at apackage.ASpec.a feature(script.groovy:15)
2727

28-
Filtered iteration [i: 5, a: 1, b: 1, c: 3]:
28+
Filtered iteration [i: 5, a: 2, b: 2, c: 2]:
2929
Condition not satisfied:
3030

3131
i == 1

0 commit comments

Comments
 (0)