1
0
mirror of synced 2025-12-19 18:14:56 -05:00

Support incremental sync in performance harness tool (#31588)

This commit is contained in:
Xiaohan Song
2023-10-20 10:29:52 -07:00
committed by GitHub
parent 5a4094a00c
commit 99b435ff71
10 changed files with 67 additions and 23 deletions

View File

@@ -44,7 +44,15 @@ on:
sync-mode: sync-mode:
description: "Sync mode to use for destination performance measurement." description: "Sync mode to use for destination performance measurement."
required: false required: false
type: choice
options:
- full_refresh
- incremental
default: "full_refresh" default: "full_refresh"
reportToDatadog:
description: "Whether to report the performance test results to Datadog."
required: false
default: "false"
jobs: jobs:
uuid: uuid:
name: "Custom UUID of workflow run" name: "Custom UUID of workflow run"
@@ -174,6 +182,7 @@ jobs:
DS: ${{ github.event.inputs.dataset }} DS: ${{ github.event.inputs.dataset }}
STREAM_NUMBER: ${{ github.event.inputs.stream-number }} STREAM_NUMBER: ${{ github.event.inputs.stream-number }}
SYNC_MODE: ${{ github.event.inputs.sync-mode }} SYNC_MODE: ${{ github.event.inputs.sync-mode }}
REPORT_TO_DATADOG: ${{ inputs.reportToDatadog }}
PREFIX: '{"type":"LOG","log":{"level":"INFO","message":"INFO i.a.i.p.PerformanceTest(runTest):165' PREFIX: '{"type":"LOG","log":{"level":"INFO","message":"INFO i.a.i.p.PerformanceTest(runTest):165'
SUFFIX: '"}}' SUFFIX: '"}}'
HARNESS_TYPE: ${{ steps.which-harness.outputs.harness_type }} HARNESS_TYPE: ${{ steps.which-harness.outputs.harness_type }}

View File

@@ -8,8 +8,8 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import io.airbyte.commons.io.IOs; import io.airbyte.commons.io.IOs;
import io.airbyte.commons.json.Jsons; import io.airbyte.commons.json.Jsons;
import io.airbyte.commons.resources.MoreResources;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays; import java.util.Arrays;
@@ -28,6 +28,7 @@ public class Main {
// TODO: (ryankfu) add function parity with destination_performance // TODO: (ryankfu) add function parity with destination_performance
int numOfParallelStreams = 1; int numOfParallelStreams = 1;
String syncMode = "full_refresh"; String syncMode = "full_refresh";
boolean reportToDatadog = false;
// TODO: (ryankfu) Integrated something akin to {@link Clis} for parsing arguments. // TODO: (ryankfu) Integrated something akin to {@link Clis} for parsing arguments.
switch (args.length) { switch (args.length) {
@@ -47,6 +48,13 @@ public class Main {
numOfParallelStreams = Integer.parseInt(args[2]); numOfParallelStreams = Integer.parseInt(args[2]);
syncMode = args[3]; syncMode = args[3];
} }
case 5 -> {
image = args[0];
dataset = args[1];
numOfParallelStreams = Integer.parseInt(args[2]);
syncMode = args[3];
reportToDatadog = Boolean.parseBoolean(args[4]);
}
default -> { default -> {
log.info("unexpected arguments"); log.info("unexpected arguments");
System.exit(1); System.exit(1);
@@ -65,7 +73,7 @@ public class Main {
final JsonNode catalog; final JsonNode catalog;
try { try {
catalog = getCatalog(dataset, connector); catalog = getCatalog(dataset, connector, syncMode);
} catch (final IOException ex) { } catch (final IOException ex) {
throw new IllegalStateException("Failed to read catalog", ex); throw new IllegalStateException("Failed to read catalog", ex);
} }
@@ -79,6 +87,8 @@ public class Main {
final PerformanceTest test = new PerformanceTest( final PerformanceTest test = new PerformanceTest(
image, image,
dataset, dataset,
syncMode,
reportToDatadog,
config.toString(), config.toString(),
catalog.toString()); catalog.toString());
test.runTest(); test.runTest();
@@ -90,11 +100,11 @@ public class Main {
System.exit(0); System.exit(0);
} }
static JsonNode getCatalog(final String dataset, final String connector) throws IOException { static JsonNode getCatalog(final String dataset, final String connector, final String syncMode) throws IOException {
final ObjectMapper objectMapper = new ObjectMapper(); final ObjectMapper objectMapper = new ObjectMapper();
final String catalogFilename = "catalogs/%s/%s_catalog.json".formatted(connector, dataset); final String catalogFilename = "catalogs/%s/%s_catalog.json".formatted(connector, dataset);
final InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(catalogFilename); final String template = MoreResources.readResource(catalogFilename);
return objectMapper.readTree(is); return objectMapper.readTree(String.format(template, syncMode));
} }
} }

View File

@@ -55,13 +55,23 @@ public class PerformanceTest {
public static final double MEGABYTE = Math.pow(1024, 2); public static final double MEGABYTE = Math.pow(1024, 2);
private final String imageName; private final String imageName;
private final String dataset; private final String dataset;
private final String syncMode;
private final boolean reportToDatadog;
private final JsonNode config; private final JsonNode config;
private final ConfiguredAirbyteCatalog catalog; private final ConfiguredAirbyteCatalog catalog;
PerformanceTest(final String imageName, final String dataset, final String config, final String catalog) throws JsonProcessingException { PerformanceTest(final String imageName,
final String dataset,
final String syncMode,
final Boolean reportToDatadog,
final String config,
final String catalog)
throws JsonProcessingException {
final ObjectMapper mapper = new ObjectMapper(); final ObjectMapper mapper = new ObjectMapper();
this.imageName = imageName; this.imageName = imageName;
this.dataset = dataset; this.dataset = dataset;
this.syncMode = syncMode;
this.reportToDatadog = reportToDatadog;
this.config = mapper.readTree(config); this.config = mapper.readTree(config);
this.catalog = Jsons.deserialize(catalog, ConfiguredAirbyteCatalog.class); this.catalog = Jsons.deserialize(catalog, ConfiguredAirbyteCatalog.class);
} }
@@ -118,6 +128,9 @@ public class PerformanceTest {
totalBytes / MEGABYTE); totalBytes / MEGABYTE);
} }
} }
if (source.getExitValue() > 0) {
throw new RuntimeException("Source failed with exit code: " + source.getExitValue());
}
log.info("Test ended successfully"); log.info("Test ended successfully");
final var end = System.currentTimeMillis(); final var end = System.currentTimeMillis();
final var totalMB = totalBytes / MEGABYTE; final var totalMB = totalBytes / MEGABYTE;
@@ -126,13 +139,17 @@ public class PerformanceTest {
final var throughput = totalMB / totalTimeSecs; final var throughput = totalMB / totalTimeSecs;
log.info("total secs: {}. total MB read: {}, rps: {}, throughput: {}", totalTimeSecs, totalMB, rps, throughput); log.info("total secs: {}. total MB read: {}, rps: {}, throughput: {}", totalTimeSecs, totalMB, rps, throughput);
source.close(); source.close();
if (!reportToDatadog) {
return;
}
final long reportingTimeInEpochSeconds = OffsetDateTime.now().toInstant().getEpochSecond(); final long reportingTimeInEpochSeconds = OffsetDateTime.now().toInstant().getEpochSecond();
List<MetricResource> metricResources = List.of( List<MetricResource> metricResources = List.of(
new MetricResource().name("github").type("runner"), new MetricResource().name("github").type("runner"),
new MetricResource().name(imageName).type("image"), new MetricResource().name(imageName).type("image"),
new MetricResource().name(dataset).type("dataset")); new MetricResource().name(dataset).type("dataset"),
new MetricResource().name(syncMode).type("syncMode"));
MetricPayload body = MetricPayload body =
new MetricPayload() new MetricPayload()
.series( .series(

View File

@@ -40,7 +40,7 @@
"supported_sync_modes": ["full_refresh", "incremental"], "supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_primary_key": [["id"]] "source_defined_primary_key": [["id"]]
}, },
"sync_mode": "full_refresh", "sync_mode": "%1$s",
"primary_key": [["id"]], "primary_key": [["id"]],
"cursor_field": ["id"], "cursor_field": ["id"],
"destination_sync_mode": "append" "destination_sync_mode": "append"
@@ -113,7 +113,7 @@
"supported_sync_modes": ["full_refresh", "incremental"], "supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_primary_key": [["id"]] "source_defined_primary_key": [["id"]]
}, },
"sync_mode": "full_refresh", "sync_mode": "%1$s",
"primary_key": [["id"]], "primary_key": [["id"]],
"cursor_field": ["updated_at"], "cursor_field": ["updated_at"],
"destination_sync_mode": "append" "destination_sync_mode": "append"
@@ -152,7 +152,7 @@
"supported_sync_modes": ["full_refresh", "incremental"], "supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_primary_key": [["id"]] "source_defined_primary_key": [["id"]]
}, },
"sync_mode": "full_refresh", "sync_mode": "%1$s",
"primary_key": [["id"]], "primary_key": [["id"]],
"cursor_field": ["created_at"], "cursor_field": ["created_at"],
"destination_sync_mode": "append" "destination_sync_mode": "append"

View File

@@ -40,7 +40,7 @@
"supported_sync_modes": ["full_refresh", "incremental"], "supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_primary_key": [["id"]] "source_defined_primary_key": [["id"]]
}, },
"sync_mode": "full_refresh", "sync_mode": "%1$s",
"primary_key": [["id"]], "primary_key": [["id"]],
"cursor_field": ["id"], "cursor_field": ["id"],
"destination_sync_mode": "append" "destination_sync_mode": "append"
@@ -113,7 +113,7 @@
"supported_sync_modes": ["full_refresh", "incremental"], "supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_primary_key": [["id"]] "source_defined_primary_key": [["id"]]
}, },
"sync_mode": "full_refresh", "sync_mode": "%1$s",
"primary_key": [["id"]], "primary_key": [["id"]],
"cursor_field": ["updated_at"], "cursor_field": ["updated_at"],
"destination_sync_mode": "append" "destination_sync_mode": "append"
@@ -152,7 +152,7 @@
"supported_sync_modes": ["full_refresh", "incremental"], "supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_primary_key": [["id"]] "source_defined_primary_key": [["id"]]
}, },
"sync_mode": "full_refresh", "sync_mode": "%1$s",
"primary_key": [["id"]], "primary_key": [["id"]],
"cursor_field": ["created_at"], "cursor_field": ["created_at"],
"destination_sync_mode": "append" "destination_sync_mode": "append"

View File

@@ -40,7 +40,7 @@
"supported_sync_modes": ["full_refresh", "incremental"], "supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_primary_key": [["id"]] "source_defined_primary_key": [["id"]]
}, },
"sync_mode": "full_refresh", "sync_mode": "%1$s",
"primary_key": [["id"]], "primary_key": [["id"]],
"cursor_field": ["id"], "cursor_field": ["id"],
"destination_sync_mode": "append" "destination_sync_mode": "append"
@@ -113,7 +113,7 @@
"supported_sync_modes": ["full_refresh", "incremental"], "supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_primary_key": [["id"]] "source_defined_primary_key": [["id"]]
}, },
"sync_mode": "full_refresh", "sync_mode": "%1$s",
"primary_key": [["id"]], "primary_key": [["id"]],
"cursor_field": ["updated_at"], "cursor_field": ["updated_at"],
"destination_sync_mode": "append" "destination_sync_mode": "append"
@@ -152,7 +152,7 @@
"supported_sync_modes": ["full_refresh", "incremental"], "supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_primary_key": [["id"]] "source_defined_primary_key": [["id"]]
}, },
"sync_mode": "full_refresh", "sync_mode": "%1$s",
"primary_key": [["id"]], "primary_key": [["id"]],
"cursor_field": ["created_at"], "cursor_field": ["created_at"],
"destination_sync_mode": "append" "destination_sync_mode": "append"

View File

@@ -69,10 +69,10 @@
"source_defined_cursor": true, "source_defined_cursor": true,
"source_defined_primary_key": [["id"]] "source_defined_primary_key": [["id"]]
}, },
"sync_mode": "full_refresh", "sync_mode": "%s",
"primary_key": [["id"]], "primary_key": [["id"]],
"cursor_field": [], "cursor_field": [],
"destination_sync_mode": "overwrite" "destination_sync_mode": "append"
} }
] ]
} }

View File

@@ -69,10 +69,10 @@
"source_defined_cursor": true, "source_defined_cursor": true,
"source_defined_primary_key": [["id"]] "source_defined_primary_key": [["id"]]
}, },
"sync_mode": "full_refresh", "sync_mode": "%s",
"primary_key": [["id"]], "primary_key": [["id"]],
"cursor_field": [], "cursor_field": [],
"destination_sync_mode": "overwrite" "destination_sync_mode": "append"
} }
] ]
} }

View File

@@ -69,10 +69,10 @@
"source_defined_cursor": true, "source_defined_cursor": true,
"source_defined_primary_key": [["id"]] "source_defined_primary_key": [["id"]]
}, },
"sync_mode": "full_refresh", "sync_mode": "%s",
"primary_key": [["id"]], "primary_key": [["id"]],
"cursor_field": [], "cursor_field": [],
"destination_sync_mode": "overwrite" "destination_sync_mode": "append"
} }
] ]
} }

View File

@@ -9,7 +9,13 @@ spec:
- name: main - name: main
image: airbyte/$HARNESS:dev image: airbyte/$HARNESS:dev
args: args:
["$CONNECTOR_IMAGE_NAME", "$DATASET", "$STREAM_NUMBER", "$SYNC_MODE"] [
"$CONNECTOR_IMAGE_NAME",
"$DATASET",
"$STREAM_NUMBER",
"$SYNC_MODE",
"$REPORT_TO_DATADOG",
]
volumeMounts: volumeMounts:
- name: secrets-volume - name: secrets-volume
mountPath: /airbyte/secrets mountPath: /airbyte/secrets
@@ -25,6 +31,8 @@ spec:
value: $DD_API_KEY value: $DD_API_KEY
- name: DD_SITE - name: DD_SITE
value: "datadoghq.com" value: "datadoghq.com"
- name: USE_STREAM_CAPABLE_STATE
value: "true"
volumes: volumes:
- name: secrets-volume - name: secrets-volume
hostPath: hostPath: