Skip to content

Commit f66b280

Browse files
authored
Improving UT coverage for DatastreamToSpanner template (#3820)
1 parent 929972f commit f66b280

4 files changed

Lines changed: 531 additions & 18 deletions

File tree

v2/datastream-to-spanner/src/main/java/com/google/cloud/teleport/v2/templates/DataStreamToSpanner.java

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@
8282
import org.apache.beam.sdk.values.PCollectionTuple;
8383
import org.apache.beam.sdk.values.PCollectionView;
8484
import org.apache.beam.sdk.values.TupleTagList;
85-
import org.joda.time.Duration;
8685
import org.slf4j.Logger;
8786
import org.slf4j.LoggerFactory;
87+
import org.threeten.bp.Duration;
8888

8989
/**
9090
* This pipeline ingests DataStream data from GCS as events. The events are written to Cloud
@@ -616,6 +616,10 @@ static String getSourceType(Options options) {
616616
LOG.error("IOException Occurred: DataStreamClient failed initialization.");
617617
throw new IllegalArgumentException("Unable to initialize DatastreamClient: " + e);
618618
}
619+
return getSourceTypeFromConfig(sourceConfig);
620+
}
621+
622+
static String getSourceTypeFromConfig(SourceConfig sourceConfig) {
619623
if (sourceConfig.getMysqlSourceConfig() != null) {
620624
return DatastreamConstants.MYSQL_SOURCE_TYPE;
621625
} else if (sourceConfig.getOracleSourceConfig() != null) {
@@ -649,6 +653,10 @@ public static void main(String[] args) {
649653
* @return The result of the pipeline execution.
650654
*/
651655
public static PipelineResult run(Options options) {
656+
return buildPipeline(options).run();
657+
}
658+
659+
static Pipeline buildPipeline(Options options) {
652660
long startTime = System.currentTimeMillis();
653661
/*
654662
* Stages:
@@ -682,13 +690,13 @@ public static PipelineResult run(Options options) {
682690
.withRpcPriority(ValueProvider.StaticValueProvider.of(options.getSpannerPriority()))
683691
.withCommitRetrySettings(
684692
RetrySettings.newBuilder()
685-
.setTotalTimeout(org.threeten.bp.Duration.ofMinutes(4))
686-
.setInitialRetryDelay(org.threeten.bp.Duration.ofMinutes(0))
693+
.setTotalTimeout(Duration.ofMinutes(4))
694+
.setInitialRetryDelay(Duration.ofMinutes(0))
687695
.setRetryDelayMultiplier(1)
688-
.setMaxRetryDelay(org.threeten.bp.Duration.ofMinutes(0))
689-
.setInitialRpcTimeout(org.threeten.bp.Duration.ofMinutes(4))
696+
.setMaxRetryDelay(Duration.ofMinutes(0))
697+
.setInitialRpcTimeout(Duration.ofMinutes(4))
690698
.setRpcTimeoutMultiplier(1)
691-
.setMaxRpcTimeout(org.threeten.bp.Duration.ofMinutes(4))
699+
.setMaxRpcTimeout(Duration.ofMinutes(4))
692700
.setMaxAttempts(1)
693701
.build());
694702
SpannerConfig shadowTableSpannerConfig = getShadowTableSpannerConfig(options);
@@ -776,7 +784,8 @@ public static PipelineResult run(Options options) {
776784
.withFileReadConcurrency(options.getFileReadConcurrency())
777785
.withoutDatastreamRecordsReshuffle()
778786
.withDirectoryWatchDuration(
779-
Duration.standardMinutes(options.getDirectoryWatchDurationInMinutes()))
787+
org.joda.time.Duration.standardMinutes(
788+
options.getDirectoryWatchDurationInMinutes()))
780789
.withDatastreamSourceType(options.getDatastreamSourceType()));
781790
int maxNumWorkers = options.getMaxNumWorkers() != 0 ? options.getMaxNumWorkers() : 1;
782791
jsonRecords =
@@ -855,7 +864,7 @@ public static PipelineResult run(Options options) {
855864
LOG.info("Filtered events directory: {}", filterEventsDirectory);
856865
transformedRecords
857866
.get(DatastreamToSpannerConstants.FILTERED_EVENT_TAG)
858-
.apply(Window.into(FixedWindows.of(Duration.standardMinutes(1))))
867+
.apply(Window.into(FixedWindows.of(org.joda.time.Duration.standardMinutes(1))))
859868
.apply(
860869
"Write Filtered Events To GCS",
861870
TextIO.write().to(filterEventsDirectory).withSuffix(".json").withWindowedWrites());
@@ -928,8 +937,7 @@ public static PipelineResult run(Options options) {
928937
.withTmpDirectory((options).getDeadLetterQueueDirectory() + "/tmp_severe/")
929938
.setIncludePaneInfo(true)
930939
.build());
931-
// Execute the pipeline and return the result.
932-
return pipeline.run();
940+
return pipeline;
933941
}
934942

935943
static SpannerConfig getShadowTableSpannerConfig(Options options) {
@@ -968,13 +976,13 @@ static SpannerConfig getShadowTableSpannerConfig(Options options) {
968976
.withRpcPriority(ValueProvider.StaticValueProvider.of(options.getSpannerPriority()))
969977
.withCommitRetrySettings(
970978
RetrySettings.newBuilder()
971-
.setTotalTimeout(org.threeten.bp.Duration.ofMinutes(4))
972-
.setInitialRetryDelay(org.threeten.bp.Duration.ofMinutes(0))
979+
.setTotalTimeout(Duration.ofMinutes(4))
980+
.setInitialRetryDelay(Duration.ofMinutes(0))
973981
.setRetryDelayMultiplier(1)
974-
.setMaxRetryDelay(org.threeten.bp.Duration.ofMinutes(0))
975-
.setInitialRpcTimeout(org.threeten.bp.Duration.ofMinutes(4))
982+
.setMaxRetryDelay(Duration.ofMinutes(0))
983+
.setInitialRpcTimeout(Duration.ofMinutes(4))
976984
.setRpcTimeoutMultiplier(1)
977-
.setMaxRpcTimeout(org.threeten.bp.Duration.ofMinutes(4))
985+
.setMaxRpcTimeout(Duration.ofMinutes(4))
978986
.setMaxAttempts(1)
979987
.build());
980988
}

v2/datastream-to-spanner/src/main/java/com/google/cloud/teleport/v2/templates/spanner/ProcessInformationSchema.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,10 @@ public ProcessInformationSchemaFn(
116116

117117
@Setup
118118
public void setup() throws Exception {
119-
spannerAccessor = SpannerAccessor.getOrCreate(spannerConfig);
119+
// Use injected spannerAccessor if available (primarily for testing)
120+
if (this.spannerAccessor == null) {
121+
this.spannerAccessor = SpannerAccessor.getOrCreate(spannerConfig);
122+
}
120123
DatabaseAdminClient databaseAdminClient = spannerAccessor.getDatabaseAdminClient();
121124
dialect =
122125
databaseAdminClient
@@ -129,7 +132,10 @@ public void setup() throws Exception {
129132
shadowTableSpannerAccessor = spannerAccessor;
130133
useSeparateShadowTableDb = false;
131134
} else {
132-
shadowTableSpannerAccessor = SpannerAccessor.getOrCreate(shadowTableSpannerConfig);
135+
// Use injected shadowTableSpannerAccessor if available (primarily for testing)
136+
if (this.shadowTableSpannerAccessor == null) {
137+
this.shadowTableSpannerAccessor = SpannerAccessor.getOrCreate(shadowTableSpannerConfig);
138+
}
133139
useSeparateShadowTableDb = true;
134140
}
135141
}
@@ -203,10 +209,15 @@ Ddl getInformationSchemaAsDdl(SpannerAccessor accessor) {
203209
BatchClient batchClient = accessor.getBatchClient();
204210
BatchReadOnlyTransaction context =
205211
batchClient.batchReadOnlyTransaction(TimestampBound.strong());
206-
InformationSchemaScanner scanner = new InformationSchemaScanner(context, dialect);
212+
InformationSchemaScanner scanner = getInformationSchemaScanner(context, dialect);
207213
return scanner.scan();
208214
}
209215

216+
InformationSchemaScanner getInformationSchemaScanner(
217+
BatchReadOnlyTransaction context, Dialect dialect) {
218+
return new InformationSchemaScanner(context, dialect);
219+
}
220+
210221
void createShadowTablesInSpanner(Ddl mainDdl, Ddl shadowTableDdl) {
211222
List<String> dataTablesWithoutShadowTables =
212223
getDataTablesWithNoShadowTables(mainDdl, shadowTableDdl);

0 commit comments

Comments
 (0)