diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index d4ee2238c..987e7728c 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -163,7 +163,7 @@ stages:
${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
_OfficialBuildIdArgs: /p:OfficialBuildId=$(BUILD.BUILDNUMBER)
HADOOP_HOME: $(Build.BinariesDirectory)\hadoop
- DOTNET_WORKER_DIR: $(CurrentDotnetWorkerDir)
+ DOTNET_WORKER_DIR: $(CurrentDotnetWorkerDir)
steps:
- task: DownloadBuildArtifacts@0
@@ -431,7 +431,7 @@ stages:
${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
_OfficialBuildIdArgs: /p:OfficialBuildId=$(BUILD.BUILDNUMBER)
HADOOP_HOME: $(Build.BinariesDirectory)\hadoop
- DOTNET_WORKER_DIR: $(BackwardCompatibleDotnetWorkerDir)
+ DOTNET_WORKER_DIR: $(BackwardCompatibleDotnetWorkerDir)
steps:
- task: DownloadBuildArtifacts@0
@@ -558,12 +558,16 @@ stages:
env:
SPARK_HOME: $(Build.BinariesDirectory)\spark-2.4.6-bin-hadoop2.7
+ # Spark 3.0.0 uses Arrow 0.15.1, which contains a new Arrow spec. This breaks backward
+ # compatibility when using Microsoft.Spark.Worker with incompatible versions of Arrow.
+ # Skip Arrow tests until the backward compatibility Worker version is updated.
- task: DotNetCoreCLI@2
displayName: 'E2E tests for Spark 3.0.0'
inputs:
command: test
projects: '**/Microsoft.Spark*.E2ETest/*.csproj'
- arguments: '--configuration $(buildConfiguration) --filter $(TestsToFilterOut)'
+ arguments: "--configuration $(buildConfiguration) --filter $(TestsToFilterOut)&\
+ (FullyQualifiedName!=Microsoft.Spark.E2ETest.IpcTests.DataFrameTests.TestGroupedMapUdf)&\
+ (FullyQualifiedName!=Microsoft.Spark.E2ETest.IpcTests.DataFrameTests.TestVectorUdf)"
env:
SPARK_HOME: $(Build.BinariesDirectory)\spark-3.0.0-bin-hadoop2.7
-
diff --git a/src/csharp/Microsoft.Spark.E2ETest/IpcTests/BroadcastTests.cs b/src/csharp/Microsoft.Spark.E2ETest/IpcTests/BroadcastTests.cs
index ef6ea71b3..511f5a122 100644
--- a/src/csharp/Microsoft.Spark.E2ETest/IpcTests/BroadcastTests.cs
+++ b/src/csharp/Microsoft.Spark.E2ETest/IpcTests/BroadcastTests.cs
@@ -1,6 +1,5 @@
using System;
using System.Linq;
-using Microsoft.Spark.E2ETest.Utils;
using Microsoft.Spark.Sql;
using Xunit;
using static Microsoft.Spark.Sql.Functions;
@@ -35,7 +34,7 @@ public BroadcastTests(SparkFixture fixture)
///
/// Test Broadcast support by using multiple broadcast variables in a UDF.
///
- [SkipIfSparkVersionIsGreaterOrEqualTo(Versions.V3_0_0)]
+ [Fact]
public void TestMultipleBroadcastWithoutEncryption()
{
var obj1 = new TestBroadcastVariable(1, "first");
@@ -56,7 +55,7 @@ public void TestMultipleBroadcastWithoutEncryption()
/// Test Broadcast.Destroy() that destroys all data and metadata related to the broadcast
/// variable and makes it inaccessible from workers.
///
- [SkipIfSparkVersionIsGreaterOrEqualTo(Versions.V3_0_0)]
+ [Fact]
public void TestDestroy()
{
var obj1 = new TestBroadcastVariable(5, "destroy");
@@ -97,7 +96,7 @@ public void TestDestroy()
/// Test Broadcast.Unpersist() deletes cached copies of the broadcast on the executors. If
/// the broadcast is used after unpersist is called, it is re-sent to the executors.
///
- [SkipIfSparkVersionIsGreaterOrEqualTo(Versions.V3_0_0)]
+ [Fact]
public void TestUnpersist()
{
var obj = new TestBroadcastVariable(1, "unpersist");
diff --git a/src/csharp/Microsoft.Spark.E2ETest/IpcTests/Sql/DataFrameTests.cs b/src/csharp/Microsoft.Spark.E2ETest/IpcTests/Sql/DataFrameTests.cs
index e830a7e42..423f026ca 100644
--- a/src/csharp/Microsoft.Spark.E2ETest/IpcTests/Sql/DataFrameTests.cs
+++ b/src/csharp/Microsoft.Spark.E2ETest/IpcTests/Sql/DataFrameTests.cs
@@ -156,7 +156,7 @@ public void TestUDF()
}
}
- [SkipIfSparkVersionIsGreaterOrEqualTo(Versions.V3_0_0)]
+ [Fact]
public void TestVectorUdf()
{
Func udf1Func =
@@ -224,7 +224,7 @@ public void TestVectorUdf()
}
}
- [SkipIfSparkVersionIsGreaterOrEqualTo(Versions.V3_0_0)]
+ [Fact]
public void TestDataFrameVectorUdf()
{
Func udf1Func =
@@ -368,7 +368,6 @@ private static RecordBatch ArrowBasedCountCharacters(RecordBatch records)
returnLength);
}
-
[SkipIfSparkVersionIsGreaterOrEqualTo(Versions.V3_0_0)]
public void TestDataFrameGroupedMapUdf()
{
diff --git a/src/csharp/Microsoft.Spark.Worker.UnitTest/CommandExecutorTests.cs b/src/csharp/Microsoft.Spark.Worker.UnitTest/CommandExecutorTests.cs
index 8978e321e..22ec4ca09 100644
--- a/src/csharp/Microsoft.Spark.Worker.UnitTest/CommandExecutorTests.cs
+++ b/src/csharp/Microsoft.Spark.Worker.UnitTest/CommandExecutorTests.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
@@ -25,8 +26,13 @@ namespace Microsoft.Spark.Worker.UnitTest
{
public class CommandExecutorTests
{
- [Fact]
- public void TestPicklingSqlCommandExecutorWithSingleCommand()
+ [Theory]
+ [MemberData(nameof(CommandExecutorData.Data), MemberType = typeof(CommandExecutorData))]
+ public void TestPicklingSqlCommandExecutorWithSingleCommand(
+ Version sparkVersion,
+#pragma warning disable xUnit1026 // Theory methods should use all of their parameters
+ IpcOptions ipcOptions)
+#pragma warning restore xUnit1026 // Theory methods should use all of their parameters
{
var udfWrapper = new Sql.PicklingUdfWrapper(
(str) => "udf: " + ((str is null) ? "NULL" : str));
@@ -61,7 +67,7 @@ public void TestPicklingSqlCommandExecutorWithSingleCommand()
SerDe.Write(inputStream, (int)SpecialLengths.END_OF_DATA_SECTION);
inputStream.Seek(0, SeekOrigin.Begin);
- CommandExecutorStat stat = new CommandExecutor().Execute(
+ CommandExecutorStat stat = new CommandExecutor(sparkVersion).Execute(
inputStream,
outputStream,
0,
@@ -98,8 +104,13 @@ public void TestPicklingSqlCommandExecutorWithSingleCommand()
Assert.Equal(outputStream.Length, outputStream.Position);
}
- [Fact]
- public void TestPicklingSqlCommandExecutorWithMultiCommands()
+ [Theory]
+ [MemberData(nameof(CommandExecutorData.Data), MemberType = typeof(CommandExecutorData))]
+ public void TestPicklingSqlCommandExecutorWithMultiCommands(
+ Version sparkVersion,
+#pragma warning disable xUnit1026 // Theory methods should use all of their parameters
+ IpcOptions ipcOptions)
+#pragma warning restore xUnit1026 // Theory methods should use all of their parameters
{
var udfWrapper1 = new Sql.PicklingUdfWrapper((str) => $"udf: {str}");
var udfWrapper2 = new Sql.PicklingUdfWrapper(
@@ -145,7 +156,7 @@ public void TestPicklingSqlCommandExecutorWithMultiCommands()
SerDe.Write(inputStream, (int)SpecialLengths.END_OF_DATA_SECTION);
inputStream.Seek(0, SeekOrigin.Begin);
- CommandExecutorStat stat = new CommandExecutor().Execute(
+ CommandExecutorStat stat = new CommandExecutor(sparkVersion).Execute(
inputStream,
outputStream,
0,
@@ -182,8 +193,13 @@ public void TestPicklingSqlCommandExecutorWithMultiCommands()
Assert.Equal(outputStream.Length, outputStream.Position);
}
- [Fact]
- public void TestPicklingSqlCommandExecutorWithEmptyInput()
+ [Theory]
+ [MemberData(nameof(CommandExecutorData.Data), MemberType = typeof(CommandExecutorData))]
+ public void TestPicklingSqlCommandExecutorWithEmptyInput(
+ Version sparkVersion,
+#pragma warning disable xUnit1026 // Theory methods should use all of their parameters
+ IpcOptions ipcOptions)
+#pragma warning restore xUnit1026 // Theory methods should use all of their parameters
{
var udfWrapper = new Sql.PicklingUdfWrapper((str) => $"udf: {str}");
var command = new SqlCommand()
@@ -208,7 +224,7 @@ public void TestPicklingSqlCommandExecutorWithEmptyInput()
SerDe.Write(inputStream, (int)SpecialLengths.END_OF_DATA_SECTION);
inputStream.Seek(0, SeekOrigin.Begin);
- CommandExecutorStat stat = new CommandExecutor().Execute(
+ CommandExecutorStat stat = new CommandExecutor(sparkVersion).Execute(
inputStream,
outputStream,
0,
@@ -222,8 +238,11 @@ public void TestPicklingSqlCommandExecutorWithEmptyInput()
Assert.Equal(0, outputStream.Length);
}
- [Fact]
- public async Task TestArrowSqlCommandExecutorWithSingleCommand()
+ [Theory]
+ [MemberData(nameof(CommandExecutorData.Data), MemberType = typeof(CommandExecutorData))]
+ public async Task TestArrowSqlCommandExecutorWithSingleCommand(
+ Version sparkVersion,
+ IpcOptions ipcOptions)
{
var udfWrapper = new Sql.ArrowUdfWrapper(
(strings) => (StringArray)ToArrowArray(
@@ -254,7 +273,8 @@ public async Task TestArrowSqlCommandExecutorWithSingleCommand()
Schema schema = new Schema.Builder()
.Field(b => b.Name("arg1").DataType(StringType.Default))
.Build();
- var arrowWriter = new ArrowStreamWriter(inputStream, schema);
+ var arrowWriter =
+ new ArrowStreamWriter(inputStream, schema, leaveOpen: false, ipcOptions);
await arrowWriter.WriteRecordBatchAsync(
new RecordBatch(
schema,
@@ -269,7 +289,7 @@ await arrowWriter.WriteRecordBatchAsync(
inputStream.Seek(0, SeekOrigin.Begin);
- CommandExecutorStat stat = new CommandExecutor().Execute(
+ CommandExecutorStat stat = new CommandExecutor(sparkVersion).Execute(
inputStream,
outputStream,
0,
@@ -295,15 +315,18 @@ await arrowWriter.WriteRecordBatchAsync(
Assert.Equal($"udf: {i}", array.GetString(i));
}
- int end = SerDe.ReadInt32(outputStream);
- Assert.Equal(0, end);
+ CheckEOS(outputStream, ipcOptions);
// Validate all the data on the stream is read.
Assert.Equal(outputStream.Length, outputStream.Position);
}
- [Fact]
- public async Task TestDataFrameSqlCommandExecutorWithSingleCommand()
+ [Theory]
+ [MemberData(nameof(CommandExecutorData.Data), MemberType = typeof(CommandExecutorData))]
+
+ public async Task TestDataFrameSqlCommandExecutorWithSingleCommand(
+ Version sparkVersion,
+ IpcOptions ipcOptions)
{
var udfWrapper = new Sql.DataFrameUdfWrapper(
(strings) => strings.Apply(cur => $"udf: {cur}"));
@@ -331,7 +354,8 @@ public async Task TestDataFrameSqlCommandExecutorWithSingleCommand()
Schema schema = new Schema.Builder()
.Field(b => b.Name("arg1").DataType(StringType.Default))
.Build();
- var arrowWriter = new ArrowStreamWriter(inputStream, schema);
+ var arrowWriter =
+ new ArrowStreamWriter(inputStream, schema, leaveOpen: false, ipcOptions);
await arrowWriter.WriteRecordBatchAsync(
new RecordBatch(
schema,
@@ -346,7 +370,7 @@ await arrowWriter.WriteRecordBatchAsync(
inputStream.Seek(0, SeekOrigin.Begin);
- CommandExecutorStat stat = new CommandExecutor().Execute(
+ CommandExecutorStat stat = new CommandExecutor(sparkVersion).Execute(
inputStream,
outputStream,
0,
@@ -372,15 +396,18 @@ await arrowWriter.WriteRecordBatchAsync(
Assert.Equal($"udf: {i}", array.GetString(i));
}
- int end = SerDe.ReadInt32(outputStream);
- Assert.Equal(0, end);
+ CheckEOS(outputStream, ipcOptions);
// Validate all the data on the stream is read.
Assert.Equal(outputStream.Length, outputStream.Position);
}
- [Fact]
- public async Task TestArrowSqlCommandExecutorWithMultiCommands()
+ [Theory]
+ [MemberData(nameof(CommandExecutorData.Data), MemberType = typeof(CommandExecutorData))]
+
+ public async Task TestArrowSqlCommandExecutorWithMultiCommands(
+ Version sparkVersion,
+ IpcOptions ipcOptions)
{
var udfWrapper1 = new Sql.ArrowUdfWrapper(
(strings) => (StringArray)ToArrowArray(
@@ -427,7 +454,8 @@ public async Task TestArrowSqlCommandExecutorWithMultiCommands()
.Field(b => b.Name("arg2").DataType(Int32Type.Default))
.Field(b => b.Name("arg3").DataType(Int32Type.Default))
.Build();
- var arrowWriter = new ArrowStreamWriter(inputStream, schema);
+ var arrowWriter =
+ new ArrowStreamWriter(inputStream, schema, leaveOpen: false, ipcOptions);
await arrowWriter.WriteRecordBatchAsync(
new RecordBatch(
schema,
@@ -444,7 +472,7 @@ await arrowWriter.WriteRecordBatchAsync(
inputStream.Seek(0, SeekOrigin.Begin);
- CommandExecutorStat stat = new CommandExecutor().Execute(
+ CommandExecutorStat stat = new CommandExecutor(sparkVersion).Execute(
inputStream,
outputStream,
0,
@@ -471,15 +499,18 @@ await arrowWriter.WriteRecordBatchAsync(
Assert.Equal(i * i, array2.Values[i]);
}
- int end = SerDe.ReadInt32(outputStream);
- Assert.Equal(0, end);
+ CheckEOS(outputStream, ipcOptions);
// Validate all the data on the stream is read.
Assert.Equal(outputStream.Length, outputStream.Position);
}
- [Fact]
- public async Task TestDataFrameSqlCommandExecutorWithMultiCommands()
+ [Theory]
+ [MemberData(nameof(CommandExecutorData.Data), MemberType = typeof(CommandExecutorData))]
+
+ public async Task TestDataFrameSqlCommandExecutorWithMultiCommands(
+ Version sparkVersion,
+ IpcOptions ipcOptions)
{
var udfWrapper1 = new Sql.DataFrameUdfWrapper(
(strings) => strings.Apply(cur => $"udf: {cur}"));
@@ -521,7 +552,8 @@ public async Task TestDataFrameSqlCommandExecutorWithMultiCommands()
.Field(b => b.Name("arg2").DataType(Int32Type.Default))
.Field(b => b.Name("arg3").DataType(Int32Type.Default))
.Build();
- var arrowWriter = new ArrowStreamWriter(inputStream, schema);
+ var arrowWriter =
+ new ArrowStreamWriter(inputStream, schema, leaveOpen: false, ipcOptions);
await arrowWriter.WriteRecordBatchAsync(
new RecordBatch(
schema,
@@ -538,7 +570,7 @@ await arrowWriter.WriteRecordBatchAsync(
inputStream.Seek(0, SeekOrigin.Begin);
- CommandExecutorStat stat = new CommandExecutor().Execute(
+ CommandExecutorStat stat = new CommandExecutor(sparkVersion).Execute(
inputStream,
outputStream,
0,
@@ -565,8 +597,7 @@ await arrowWriter.WriteRecordBatchAsync(
Assert.Equal(i * i, array2.Values[i]);
}
- int end = SerDe.ReadInt32(outputStream);
- Assert.Equal(0, end);
+ CheckEOS(outputStream, ipcOptions);
// Validate all the data on the stream is read.
Assert.Equal(outputStream.Length, outputStream.Position);
@@ -577,8 +608,12 @@ await arrowWriter.WriteRecordBatchAsync(
/// Schema, and no record batches, that CommandExecutor writes the
/// appropriate response back.
///
- [Fact]
- public void TestArrowSqlCommandExecutorWithEmptyInput()
+ [Theory]
+ [MemberData(nameof(CommandExecutorData.Data), MemberType = typeof(CommandExecutorData))]
+
+ public void TestArrowSqlCommandExecutorWithEmptyInput(
+ Version sparkVersion,
+ IpcOptions ipcOptions)
{
var udfWrapper = new Sql.ArrowUdfWrapper(
(strings) => (StringArray)ToArrowArray(
@@ -607,7 +642,8 @@ public void TestArrowSqlCommandExecutorWithEmptyInput()
Schema schema = new Schema.Builder()
.Field(b => b.Name("arg1").DataType(StringType.Default))
.Build();
- var arrowWriter = new ArrowStreamWriter(inputStream, schema);
+ var arrowWriter =
+ new ArrowStreamWriter(inputStream, schema, leaveOpen: false, ipcOptions);
// The .NET ArrowStreamWriter doesn't currently support writing just a
// schema with no batches - but Java does. We use Reflection to simulate
@@ -624,7 +660,7 @@ public void TestArrowSqlCommandExecutorWithEmptyInput()
inputStream.Seek(0, SeekOrigin.Begin);
- CommandExecutorStat stat = new CommandExecutor().Execute(
+ CommandExecutorStat stat = new CommandExecutor(sparkVersion).Execute(
inputStream,
outputStream,
0,
@@ -650,8 +686,7 @@ public void TestArrowSqlCommandExecutorWithEmptyInput()
var array = (StringArray)outputBatch.Arrays.ElementAt(0);
Assert.Equal(0, array.Length);
- int end = SerDe.ReadInt32(outputStream);
- Assert.Equal(0, end);
+ CheckEOS(outputStream, ipcOptions);
// Validate all the data on the stream is read.
Assert.Equal(outputStream.Length, outputStream.Position);
@@ -662,8 +697,12 @@ public void TestArrowSqlCommandExecutorWithEmptyInput()
/// Schema, and no record batches, that CommandExecutor writes the
/// appropriate response back.
///
- [Fact]
- public void TestDataFrameSqlCommandExecutorWithEmptyInput()
+ [Theory]
+ [MemberData(nameof(CommandExecutorData.Data), MemberType = typeof(CommandExecutorData))]
+
+ public void TestDataFrameSqlCommandExecutorWithEmptyInput(
+ Version sparkVersion,
+ IpcOptions ipcOptions)
{
var udfWrapper = new Sql.DataFrameUdfWrapper(
(strings) => strings.Apply(cur=> $"udf: {cur}"));
@@ -689,7 +728,7 @@ public void TestDataFrameSqlCommandExecutorWithEmptyInput()
Schema schema = new Schema.Builder()
.Field(b => b.Name("arg1").DataType(StringType.Default))
.Build();
- var arrowWriter = new ArrowStreamWriter(inputStream, schema);
+ var arrowWriter = new ArrowStreamWriter(inputStream, schema, false, ipcOptions);
// The .NET ArrowStreamWriter doesn't currently support writing just a
// schema with no batches - but Java does. We use Reflection to simulate
@@ -706,7 +745,7 @@ public void TestDataFrameSqlCommandExecutorWithEmptyInput()
inputStream.Seek(0, SeekOrigin.Begin);
- CommandExecutorStat stat = new CommandExecutor().Execute(
+ CommandExecutorStat stat = new CommandExecutor(sparkVersion).Execute(
inputStream,
outputStream,
0,
@@ -732,15 +771,18 @@ public void TestDataFrameSqlCommandExecutorWithEmptyInput()
var array = (StringArray)outputBatch.Arrays.ElementAt(0);
Assert.Equal(0, array.Length);
- int end = SerDe.ReadInt32(outputStream);
- Assert.Equal(0, end);
+ CheckEOS(outputStream, ipcOptions);
// Validate all the data on the stream is read.
Assert.Equal(outputStream.Length, outputStream.Position);
}
- [Fact]
- public async Task TestArrowGroupedMapCommandExecutor()
+ [Theory]
+ [MemberData(nameof(CommandExecutorData.Data), MemberType = typeof(CommandExecutorData))]
+
+ public async Task TestArrowGroupedMapCommandExecutor(
+ Version sparkVersion,
+ IpcOptions ipcOptions)
{
StringArray ConvertStrings(StringArray strings)
{
@@ -793,11 +835,12 @@ Int64Array ConvertInt64s(Int64Array int64s)
int numRows = 10;
// Write test data to the input stream.
- var schema = new Schema.Builder()
+ Schema schema = new Schema.Builder()
.Field(b => b.Name("arg1").DataType(StringType.Default))
.Field(b => b.Name("arg2").DataType(Int64Type.Default))
.Build();
- var arrowWriter = new ArrowStreamWriter(inputStream, schema);
+ var arrowWriter =
+ new ArrowStreamWriter(inputStream, schema, leaveOpen: false, ipcOptions);
await arrowWriter.WriteRecordBatchAsync(
new RecordBatch(
schema,
@@ -816,7 +859,7 @@ await arrowWriter.WriteRecordBatchAsync(
inputStream.Seek(0, SeekOrigin.Begin);
- CommandExecutorStat stat = new CommandExecutor().Execute(
+ CommandExecutorStat stat = new CommandExecutor(sparkVersion).Execute(
inputStream,
outputStream,
0,
@@ -848,15 +891,18 @@ await arrowWriter.WriteRecordBatchAsync(
Assert.Equal(100 + i, longArray.Values[i]);
}
- int end = SerDe.ReadInt32(outputStream);
- Assert.Equal(0, end);
+ CheckEOS(outputStream, ipcOptions);
// Validate all the data on the stream is read.
Assert.Equal(outputStream.Length, outputStream.Position);
}
- [Fact]
- public async Task TestDataFrameGroupedMapCommandExecutor()
+ [Theory]
+ [MemberData(nameof(CommandExecutorData.Data), MemberType = typeof(CommandExecutorData))]
+
+ public async Task TestDataFrameGroupedMapCommandExecutor(
+ Version sparkVersion,
+ IpcOptions ipcOptions)
{
ArrowStringDataFrameColumn ConvertStrings(ArrowStringDataFrameColumn strings)
{
@@ -896,11 +942,12 @@ ArrowStringDataFrameColumn ConvertStrings(ArrowStringDataFrameColumn strings)
int numRows = 10;
// Write test data to the input stream.
- var schema = new Schema.Builder()
+ Schema schema = new Schema.Builder()
.Field(b => b.Name("arg1").DataType(StringType.Default))
.Field(b => b.Name("arg2").DataType(Int64Type.Default))
.Build();
- var arrowWriter = new ArrowStreamWriter(inputStream, schema);
+ var arrowWriter =
+ new ArrowStreamWriter(inputStream, schema, leaveOpen: false, ipcOptions);
await arrowWriter.WriteRecordBatchAsync(
new RecordBatch(
schema,
@@ -919,7 +966,7 @@ await arrowWriter.WriteRecordBatchAsync(
inputStream.Seek(0, SeekOrigin.Begin);
- CommandExecutorStat stat = new CommandExecutor().Execute(
+ CommandExecutorStat stat = new CommandExecutor(sparkVersion).Execute(
inputStream,
outputStream,
0,
@@ -951,15 +998,17 @@ await arrowWriter.WriteRecordBatchAsync(
Assert.Equal(100 + i, doubleArray.Values[i]);
}
- int end = SerDe.ReadInt32(outputStream);
- Assert.Equal(0, end);
+ CheckEOS(outputStream, ipcOptions);
// Validate all the data on the stream is read.
Assert.Equal(outputStream.Length, outputStream.Position);
}
- [Fact]
- public void TestRDDCommandExecutor()
+ [Theory]
+ [MemberData(nameof(CommandExecutorData.Data), MemberType = typeof(CommandExecutorData))]
+#pragma warning disable xUnit1026 // Theory methods should use all of their parameters
+ public void TestRDDCommandExecutor(Version sparkVersion, IpcOptions ipcOptions)
+#pragma warning restore xUnit1026 // Theory methods should use all of their parameters
{
static int mapUdf(int a) => a + 3;
var command = new RDDCommand()
@@ -1002,7 +1051,7 @@ public void TestRDDCommandExecutor()
inputStream.Seek(0, SeekOrigin.Begin);
// Execute the command.
- CommandExecutorStat stat = new CommandExecutor().Execute(
+ CommandExecutorStat stat = new CommandExecutor(sparkVersion).Execute(
inputStream,
outputStream,
0,
@@ -1026,5 +1075,42 @@ public void TestRDDCommandExecutor()
// Validate all the data on the stream is read.
Assert.Equal(outputStream.Length, outputStream.Position);
}
+
+ private void CheckEOS(Stream stream, IpcOptions ipcOptions)
+ {
+ if (!ipcOptions.WriteLegacyIpcFormat)
+ {
+ int continuationToken = SerDe.ReadInt32(stream);
+ Assert.Equal(-1, continuationToken);
+ }
+
+ int end = SerDe.ReadInt32(stream);
+ Assert.Equal(0, end);
+ }
+ }
+
+ public class CommandExecutorData
+ {
+ // CommandExecutor only changes its behavior between major versions.
+ public static IEnumerable