From 4629c9aa5fcd653ab65da897dbf7e3eb9e65db85 Mon Sep 17 00:00:00 2001 From: Jorge Padilla Date: Tue, 31 Oct 2023 19:08:40 -0500 Subject: [PATCH 01/19] fix(frontend): fix scroll behavior in test specs list (#3320) --- .../RunDetailTest/RunDetailTest.styled.ts | 6 +++-- .../components/RunDetailTest/TestPanel.tsx | 24 +++++++++---------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/web/src/components/RunDetailTest/RunDetailTest.styled.ts b/web/src/components/RunDetailTest/RunDetailTest.styled.ts index 89358c96af..d0301af8ab 100644 --- a/web/src/components/RunDetailTest/RunDetailTest.styled.ts +++ b/web/src/components/RunDetailTest/RunDetailTest.styled.ts @@ -16,10 +16,11 @@ export const SectionLeft = styled(Section)` z-index: 1; `; -export const SectionRight = styled(Section)<{$shouldScroll: boolean}>` +export const SectionRight = styled(Section)` background-color: ${({theme}) => theme.color.white}; box-shadow: 0 20px 24px rgba(153, 155, 168, 0.18); - overflow-y: ${({$shouldScroll}) => ($shouldScroll ? 'scroll' : 'hidden')}; + overflow: hidden; + position: relative; z-index: 2; `; @@ -32,6 +33,7 @@ export const SwitchContainer = styled.div` export const TabsContainer = styled.div` height: 100%; + overflow-y: auto; padding: 24px; position: relative; diff --git a/web/src/components/RunDetailTest/TestPanel.tsx b/web/src/components/RunDetailTest/TestPanel.tsx index c8ca511aff..663fbd6c1f 100644 --- a/web/src/components/RunDetailTest/TestPanel.tsx +++ b/web/src/components/RunDetailTest/TestPanel.tsx @@ -123,7 +123,7 @@ const TestPanel = ({run, testId, runEvents}: IProps) => { /> - + {isTestSpecFormOpen && ( { @@ -202,19 +202,19 @@ const TestPanel = ({run, testId, runEvents}: IProps) => { - - )} + + From 586a3a41f6f23a27fef8b174f82aca7892ec4320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adnan=20Rahi=C4=87?= Date: Wed, 1 Nov 2023 09:45:53 +0100 Subject: [PATCH 02/19] docs(mdx): Migrate files to `.mdx` and add meta title + desc (#3323) * docs(convert mdx): round 1 * docs(migrate to mdx): concepts * docs(migrate to mdx): cli section * docs(migrate to mdx): config section * docs(migrate to mdx): core section * docs(migrate to mdx): examples-tutorials section * docs(migrate to mdx): getting started section * docs(migrate to mdx): tools and integrations * docs(migrating to mdx): web ui * docs(migrate to mdx): fix broken links --- .../analyzer/{concepts.md => concepts.mdx} | 21 ++++- docs/docs/analyzer/plugins/common-problems.md | 7 -- .../docs/analyzer/plugins/common-problems.mdx | 18 ++++ .../plugins/otel-semantic-conventions.md | 10 -- .../plugins/otel-semantic-conventions.mdx | 21 +++++ docs/docs/analyzer/plugins/security.md | 8 -- docs/docs/analyzer/plugins/security.mdx | 19 ++++ docs/docs/analyzer/rules/attribute-naming.md | 28 ------ docs/docs/analyzer/rules/attribute-naming.mdx | 39 ++++++++ ...no-api-key-leak.md => no-api-key-leak.mdx} | 13 ++- ...-attributes.md => no-empty-attributes.mdx} | 13 ++- .../rules/{prefer-dns.md => prefer-dns.mdx} | 17 +++- ...-attributes.md => required-attributes.mdx} | 13 ++- ...-protocol.md => secure-https-protocol.mdx} | 13 ++- .../rules/{span-naming.md => span-naming.mdx} | 19 +++- ...ipeline.md => github-actions-pipeline.mdx} | 13 ++- .../{overview.md => overview.mdx} | 21 ++++- ...tekton-pipeline.md => tekton-pipeline.mdx} | 13 ++- ...kube-pipeline.md => testkube-pipeline.mdx} | 15 ++- ...ence.md => cli-installation-reference.mdx} | 15 ++- ...g-your-cli.md => configuring-your-cli.mdx} | 13 ++- ...ata-stores.md => creating-data-stores.mdx} | 17 +++- ...t-outputs.md => creating-test-outputs.mdx} | 19 +++- ...ns.md => creating-test-specifications.mdx} | 17 +++- ...est-suites.md => creating-test-suites.mdx} | 17 +++- .../{creating-tests.md => creating-tests.mdx} | 17 +++- ...ble-sets.md => creating-variable-sets.mdx} | 17 +++- docs/docs/cli/exporting-tests.md | 0 ...test-suites.md => running-test-suites.mdx} | 15 ++- .../{running-tests.md => running-tests.mdx} | 15 ++- ...d-variables.md => undefined-variables.mdx} | 15 ++- .../{ad-hoc-testing.md => ad-hoc-testing.mdx} | 17 +++- docs/docs/concepts/agent.mdx | 4 +- docs/docs/concepts/architecture.md | 5 - docs/docs/concepts/architecture.mdx | 16 ++++ .../{assertions.md => assertions.mdx} | 13 ++- docs/docs/concepts/data-stores.md | 0 docs/docs/concepts/environments.mdx | 4 +- .../{expressions.md => expressions.mdx} | 39 +++++--- docs/docs/concepts/organizations.mdx | 2 +- .../concepts/{selectors.md => selectors.mdx} | 14 ++- .../{test-suites.md => test-suites.mdx} | 19 +++- docs/docs/concepts/tests.md | 0 .../{variable-sets.md => variable-sets.mdx} | 13 ++- .../{versioning.md => versioning.mdx} | 19 +++- ...ing.md => what-is-trace-based-testing.mdx} | 51 +++++----- docs/docs/concepts/what-is-tracing.md | 0 docs/docs/configuration/agent.mdx | 2 +- .../configuration/config-file-reference.md | 0 .../{awsxray.md => awsxray.mdx} | 17 +++- ...app-insights.md => azure-app-insights.mdx} | 19 +++- .../{datadog.md => datadog.mdx} | 15 ++- .../{dynatrace.md => dynatrace.mdx} | 21 +++-- .../{elasticapm.md => elasticapm.mdx} | 19 +++- .../{honeycomb.md => honeycomb.mdx} | 15 ++- .../{jaeger.md => jaeger.mdx} | 19 +++- .../{lightstep.md => lightstep.mdx} | 17 +++- .../{new-relic.md => new-relic.mdx} | 17 +++- .../{opensearch.md => opensearch.mdx} | 19 +++- ...llector.md => opentelemetry-collector.mdx} | 16 +++- .../{signalfx.md => signalfx.mdx} | 16 +++- .../{signoz.md => signoz.mdx} | 44 +++++---- .../{tempo.md => tempo.mdx} | 21 +++-- docs/docs/configuration/{demo.md => demo.mdx} | 13 ++- ...ollector-configuration-file-reference.mdx} | 38 +++++--- docs/docs/configuration/overview.mdx | 34 +++---- ...-spans.md => sampling-tracetest-spans.mdx} | 13 ++- .../{test-runner.md => test-runner.mdx} | 16 +++- .../{trace-polling.md => trace-polling.mdx} | 13 ++- ...est-analyzer.md => tracetest-analyzer.mdx} | 17 +++- docs/docs/core/configuration/analytics.mdx | 4 +- docs/docs/core/configuration/overview.mdx | 24 ++--- docs/docs/core/configuration/provisioning.mdx | 4 +- docs/docs/core/configuration/server.mdx | 6 +- docs/docs/core/configuration/telemetry.mdx | 8 +- docs/docs/core/configuration/upgrade.mdx | 4 +- .../core/deployment/{docker.md => docker.mdx} | 20 +++- docs/docs/core/deployment/kubernetes.mdx | 27 +++--- .../deployment/{overview.md => overview.mdx} | 21 +++-- .../core/getting-started/installation.mdx | 22 ++--- docs/docs/core/getting-started/open.mdx | 6 +- docs/docs/core/getting-started/overview.mdx | 2 +- docs/docs/examples-tutorials/overview.mdx | 2 +- docs/docs/examples-tutorials/recipes.mdx | 60 ++++++------ ...opentelemetry-collector-and-tracetest.mdx} | 14 ++- ... running-tracetest-with-aws-terraform.mdx} | 16 +++- ...running-tracetest-with-aws-x-ray-adot.mdx} | 16 +++- ...ing-tracetest-with-aws-x-ray-pokeshop.mdx} | 16 +++- ...d => running-tracetest-with-aws-x-ray.mdx} | 16 +++- ...est-with-azure-app-insights-collector.mdx} | 16 +++- ...test-with-azure-app-insights-pokeshop.mdx} | 18 +++- ...ing-tracetest-with-azure-app-insights.mdx} | 16 +++- ....md => running-tracetest-with-datadog.mdx} | 14 ++- ...d => running-tracetest-with-dynatrace.mdx} | 16 +++- ... => running-tracetest-with-elasticapm.mdx} | 14 ++- ...d => running-tracetest-with-honeycomb.mdx} | 18 +++- ...r.md => running-tracetest-with-jaeger.mdx} | 14 ++- ...d => running-tracetest-with-lightstep.mdx} | 14 ++- ...d => running-tracetest-with-new-relic.mdx} | 16 +++- ... => running-tracetest-with-opensearch.mdx} | 14 ++- ...unning-tracetest-with-signoz-pokeshop.mdx} | 16 +++- ...acetest-with-step-functions-terraform.mdx} | 14 ++- ...po.md => running-tracetest-with-tempo.mdx} | 14 ++- ...ata-store-with-manual-instrumentation.mdx} | 14 ++- ...g-tracetest-without-a-trace-data-store.mdx | 7 +- ...ka-go-api-with-opentelemetry-tracetest.mdx | 4 +- docs/docs/examples-tutorials/tutorials.mdx | 2 +- docs/docs/examples-tutorials/videos.mdx | 2 +- docs/docs/examples-tutorials/webinars.mdx | 2 +- docs/docs/getting-started/installation.mdx | 4 +- docs/docs/getting-started/no-otel.mdx | 4 +- docs/docs/getting-started/open.mdx | 8 +- docs/docs/getting-started/overview.mdx | 2 +- docs/docs/index.mdx | 2 +- .../use-cases/add-item-into-shopping-cart.md | 4 +- .../use-cases/check-shopping-cart-contents.md | 4 +- .../opentelemetry-store/use-cases/checkout.md | 4 +- .../use-cases/get-recommended-products.md | 4 +- .../use-cases/user-purchasing-products.md | 8 +- .../pokeshop/use-cases/add-pokemon.md | 5 +- .../pokeshop/use-cases/get-pokemon-by-id.md | 5 +- .../use-cases/import-pokemon-from-stream.md | 4 +- .../pokeshop/use-cases/import-pokemon.md | 4 +- .../pokeshop/use-cases/list-pokemon.md | 4 +- docs/docs/quick-start.md | 37 -------- docs/docs/run-affected-spans.md | 26 ------ docs/docs/run-exports.md | 24 ----- docs/docs/run-locally.md | 92 ------------------- docs/docs/run-text-search.md | 13 --- docs/docs/server-configuration.md | 53 ----------- .../tools-and-integrations/{k6.md => k6.mdx} | 13 ++- .../{keptn.md => keptn.mdx} | 15 ++- docs/docs/tools-and-integrations/overview.md | 11 --- docs/docs/tools-and-integrations/overview.mdx | 22 +++++ .../{testkube.md => testkube.mdx} | 13 ++- ...ata-stores.md => creating-data-stores.mdx} | 16 +++- ...t-outputs.md => creating-test-outputs.mdx} | 18 +++- ...ns.md => creating-test-specifications.mdx} | 14 ++- ...est-suites.md => creating-test-suites.mdx} | 18 +++- .../{creating-tests.md => creating-tests.mdx} | 16 +++- ...ble-sets.md => creating-variable-sets.mdx} | 16 +++- docs/docs/web-ui/editing-tests.md | 29 ------ ...exporting-tests.md => exporting-tests.mdx} | 15 ++- .../{test-results.md => test-results.mdx} | 14 ++- ...d-variables.md => undefined-variables.mdx} | 16 +++- docs/docs/working-with-traces.md | 17 ---- docs/sidebars.js | 24 ++--- 147 files changed, 1481 insertions(+), 785 deletions(-) rename docs/docs/analyzer/{concepts.md => concepts.mdx} (80%) delete mode 100644 docs/docs/analyzer/plugins/common-problems.md create mode 100644 docs/docs/analyzer/plugins/common-problems.mdx delete mode 100644 docs/docs/analyzer/plugins/otel-semantic-conventions.md create mode 100644 docs/docs/analyzer/plugins/otel-semantic-conventions.mdx delete mode 100644 docs/docs/analyzer/plugins/security.md create mode 100644 docs/docs/analyzer/plugins/security.mdx delete mode 100644 docs/docs/analyzer/rules/attribute-naming.md create mode 100644 docs/docs/analyzer/rules/attribute-naming.mdx rename docs/docs/analyzer/rules/{no-api-key-leak.md => no-api-key-leak.mdx} (66%) rename docs/docs/analyzer/rules/{no-empty-attributes.md => no-empty-attributes.mdx} (60%) rename docs/docs/analyzer/rules/{prefer-dns.md => prefer-dns.mdx} (64%) rename docs/docs/analyzer/rules/{required-attributes.md => required-attributes.mdx} (77%) rename docs/docs/analyzer/rules/{secure-https-protocol.md => secure-https-protocol.mdx} (66%) rename docs/docs/analyzer/rules/{span-naming.md => span-naming.mdx} (53%) rename docs/docs/ci-cd-automation/{github-actions-pipeline.md => github-actions-pipeline.mdx} (97%) rename docs/docs/ci-cd-automation/{overview.md => overview.mdx} (67%) rename docs/docs/ci-cd-automation/{tekton-pipeline.md => tekton-pipeline.mdx} (97%) rename docs/docs/ci-cd-automation/{testkube-pipeline.md => testkube-pipeline.mdx} (97%) rename docs/docs/cli/{cli-installation-reference.md => cli-installation-reference.mdx} (84%) rename docs/docs/cli/{configuring-your-cli.md => configuring-your-cli.mdx} (84%) rename docs/docs/cli/{creating-data-stores.md => creating-data-stores.mdx} (79%) rename docs/docs/cli/{creating-test-outputs.md => creating-test-outputs.mdx} (71%) rename docs/docs/cli/{creating-test-specifications.md => creating-test-specifications.mdx} (90%) rename docs/docs/cli/{creating-test-suites.md => creating-test-suites.mdx} (62%) rename docs/docs/cli/{creating-tests.md => creating-tests.mdx} (93%) rename docs/docs/cli/{creating-variable-sets.md => creating-variable-sets.mdx} (66%) delete mode 100644 docs/docs/cli/exporting-tests.md rename docs/docs/cli/{running-test-suites.md => running-test-suites.mdx} (79%) rename docs/docs/cli/{running-tests.md => running-tests.mdx} (93%) rename docs/docs/cli/{undefined-variables.md => undefined-variables.mdx} (69%) rename docs/docs/concepts/{ad-hoc-testing.md => ad-hoc-testing.mdx} (82%) delete mode 100644 docs/docs/concepts/architecture.md create mode 100644 docs/docs/concepts/architecture.mdx rename docs/docs/concepts/{assertions.md => assertions.mdx} (82%) delete mode 100644 docs/docs/concepts/data-stores.md rename docs/docs/concepts/{expressions.md => expressions.mdx} (86%) rename docs/docs/concepts/{selectors.md => selectors.mdx} (98%) rename docs/docs/concepts/{test-suites.md => test-suites.mdx} (77%) delete mode 100644 docs/docs/concepts/tests.md rename docs/docs/concepts/{variable-sets.md => variable-sets.mdx} (85%) rename docs/docs/concepts/{versioning.md => versioning.mdx} (74%) rename docs/docs/concepts/{what-is-trace-based-testing.md => what-is-trace-based-testing.mdx} (72%) delete mode 100644 docs/docs/concepts/what-is-tracing.md delete mode 100644 docs/docs/configuration/config-file-reference.md rename docs/docs/configuration/connecting-to-data-stores/{awsxray.md => awsxray.mdx} (75%) rename docs/docs/configuration/connecting-to-data-stores/{azure-app-insights.md => azure-app-insights.mdx} (81%) rename docs/docs/configuration/connecting-to-data-stores/{datadog.md => datadog.mdx} (86%) rename docs/docs/configuration/connecting-to-data-stores/{dynatrace.md => dynatrace.mdx} (88%) rename docs/docs/configuration/connecting-to-data-stores/{elasticapm.md => elasticapm.mdx} (79%) rename docs/docs/configuration/connecting-to-data-stores/{honeycomb.md => honeycomb.mdx} (85%) rename docs/docs/configuration/connecting-to-data-stores/{jaeger.md => jaeger.mdx} (74%) rename docs/docs/configuration/connecting-to-data-stores/{lightstep.md => lightstep.mdx} (86%) rename docs/docs/configuration/connecting-to-data-stores/{new-relic.md => new-relic.mdx} (87%) rename docs/docs/configuration/connecting-to-data-stores/{opensearch.md => opensearch.mdx} (75%) rename docs/docs/configuration/connecting-to-data-stores/{opentelemetry-collector.md => opentelemetry-collector.mdx} (84%) rename docs/docs/configuration/connecting-to-data-stores/{signalfx.md => signalfx.mdx} (72%) rename docs/docs/configuration/connecting-to-data-stores/{signoz.md => signoz.mdx} (68%) rename docs/docs/configuration/connecting-to-data-stores/{tempo.md => tempo.mdx} (87%) rename docs/docs/configuration/{demo.md => demo.mdx} (81%) rename docs/docs/configuration/{opentelemetry-collector-configuration-file-reference.md => opentelemetry-collector-configuration-file-reference.mdx} (85%) rename docs/docs/configuration/{sampling-tracetest-spans.md => sampling-tracetest-spans.mdx} (87%) rename docs/docs/configuration/{test-runner.md => test-runner.mdx} (58%) rename docs/docs/configuration/{trace-polling.md => trace-polling.mdx} (85%) rename docs/docs/configuration/{tracetest-analyzer.md => tracetest-analyzer.mdx} (74%) rename docs/docs/core/deployment/{docker.md => docker.mdx} (72%) rename docs/docs/core/deployment/{overview.md => overview.mdx} (68%) rename docs/docs/examples-tutorials/recipes/{running-python-app-with-opentelemetry-collector-and-tracetest.md => running-python-app-with-opentelemetry-collector-and-tracetest.mdx} (93%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-aws-terraform.md => running-tracetest-with-aws-terraform.mdx} (95%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-aws-x-ray-adot.md => running-tracetest-with-aws-x-ray-adot.mdx} (91%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-aws-x-ray-pokeshop.md => running-tracetest-with-aws-x-ray-pokeshop.mdx} (94%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-aws-x-ray.md => running-tracetest-with-aws-x-ray.mdx} (92%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-azure-app-insights-collector.md => running-tracetest-with-azure-app-insights-collector.mdx} (91%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-azure-app-insights-pokeshop.md => running-tracetest-with-azure-app-insights-pokeshop.mdx} (93%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-azure-app-insights.md => running-tracetest-with-azure-app-insights.mdx} (91%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-datadog.md => running-tracetest-with-datadog.mdx} (96%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-dynatrace.md => running-tracetest-with-dynatrace.mdx} (96%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-elasticapm.md => running-tracetest-with-elasticapm.mdx} (94%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-honeycomb.md => running-tracetest-with-honeycomb.mdx} (93%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-jaeger.md => running-tracetest-with-jaeger.mdx} (95%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-lightstep.md => running-tracetest-with-lightstep.mdx} (96%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-new-relic.md => running-tracetest-with-new-relic.mdx} (95%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-opensearch.md => running-tracetest-with-opensearch.mdx} (95%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-signoz-pokeshop.md => running-tracetest-with-signoz-pokeshop.mdx} (97%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-step-functions-terraform.md => running-tracetest-with-step-functions-terraform.mdx} (93%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-with-tempo.md => running-tracetest-with-tempo.mdx} (95%) rename docs/docs/examples-tutorials/recipes/{running-tracetest-without-a-trace-data-store-with-manual-instrumentation.md => running-tracetest-without-a-trace-data-store-with-manual-instrumentation.mdx} (95%) delete mode 100644 docs/docs/quick-start.md delete mode 100644 docs/docs/run-affected-spans.md delete mode 100644 docs/docs/run-exports.md delete mode 100644 docs/docs/run-locally.md delete mode 100644 docs/docs/run-text-search.md delete mode 100644 docs/docs/server-configuration.md rename docs/docs/tools-and-integrations/{k6.md => k6.mdx} (97%) rename docs/docs/tools-and-integrations/{keptn.md => keptn.mdx} (95%) delete mode 100644 docs/docs/tools-and-integrations/overview.md create mode 100644 docs/docs/tools-and-integrations/overview.mdx rename docs/docs/tools-and-integrations/{testkube.md => testkube.mdx} (94%) rename docs/docs/web-ui/{creating-data-stores.md => creating-data-stores.mdx} (55%) rename docs/docs/web-ui/{creating-test-outputs.md => creating-test-outputs.mdx} (69%) rename docs/docs/web-ui/{creating-test-specifications.md => creating-test-specifications.mdx} (82%) rename docs/docs/web-ui/{creating-test-suites.md => creating-test-suites.mdx} (70%) rename docs/docs/web-ui/{creating-tests.md => creating-tests.mdx} (75%) rename docs/docs/web-ui/{creating-variable-sets.md => creating-variable-sets.mdx} (55%) delete mode 100644 docs/docs/web-ui/editing-tests.md rename docs/docs/web-ui/{exporting-tests.md => exporting-tests.mdx} (77%) rename docs/docs/web-ui/{test-results.md => test-results.mdx} (83%) rename docs/docs/web-ui/{undefined-variables.md => undefined-variables.mdx} (50%) delete mode 100644 docs/docs/working-with-traces.md diff --git a/docs/docs/analyzer/concepts.md b/docs/docs/analyzer/concepts.mdx similarity index 80% rename from docs/docs/analyzer/concepts.md rename to docs/docs/analyzer/concepts.mdx index 02abad6ac3..3f0d58bb54 100644 --- a/docs/docs/analyzer/concepts.md +++ b/docs/docs/analyzer/concepts.mdx @@ -1,12 +1,23 @@ -# Trace Analyzer Concepts +--- +id: concepts +title: Trace Analyzer Concepts +description: The Tracetest Analyzer analyzes OpenTelemetry traces to help teams improve instrumentation data, find potential problems, and provide tips to fix the problems. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- The Tracetest Analyzer is a plugin-based framework used to analyze OpenTelemetry traces to help teams improve their instrumentation data, find potential problems and provide tips to fix the problems. ## Plugins -- [OpenTelemetry Semantic Conventions](./plugins/otel-semantic-conventions.md) -- [Security](./plugins/security.md) -- [Common Problems](./plugins/common-problems.md) +- [OpenTelemetry Semantic Conventions](./plugins/otel-semantic-conventions) +- [Security](./plugins/security) +- [Common Problems](./plugins/common-problems) ## Problem @@ -40,7 +51,7 @@ There are two main rule types: - Single Trace. Encapsulated to the current trace, no external data is required. :::note -[This documentation will be focused on single trace rules for timing purposes.](../configuration/tracetest-analyzer.md) +[This documentation will be focused on single trace rules for timing purposes.](../configuration/tracetest-analyzer) ::: ### Analyzer Resource diff --git a/docs/docs/analyzer/plugins/common-problems.md b/docs/docs/analyzer/plugins/common-problems.md deleted file mode 100644 index 1e293f0539..0000000000 --- a/docs/docs/analyzer/plugins/common-problems.md +++ /dev/null @@ -1,7 +0,0 @@ -# Common Problems - -The `Common Problems` plugin is responsible of analyzing the spans that are part of a trace in order to identify frequent mistakes in the distributed system. - -## Rules - -- [prefer-dns](../rules/prefer-dns.md) diff --git a/docs/docs/analyzer/plugins/common-problems.mdx b/docs/docs/analyzer/plugins/common-problems.mdx new file mode 100644 index 0000000000..b4d1d0819f --- /dev/null +++ b/docs/docs/analyzer/plugins/common-problems.mdx @@ -0,0 +1,18 @@ +--- +id: common-problems +title: Common Problems +description: The Common Problems plugin analyzes spans part of a trace to identify errors. The Tracetest Analyzer analyzes OpenTelemetry traces. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- + +The `Common Problems` plugin is responsible of analyzing the spans that are part of a trace in order to identify frequent mistakes in the distributed system. + +## Rules + +- [prefer-dns](/analyzer/rules/prefer-dns) diff --git a/docs/docs/analyzer/plugins/otel-semantic-conventions.md b/docs/docs/analyzer/plugins/otel-semantic-conventions.md deleted file mode 100644 index a2b34254ef..0000000000 --- a/docs/docs/analyzer/plugins/otel-semantic-conventions.md +++ /dev/null @@ -1,10 +0,0 @@ -# OTel Semantic Conventions - -The `OpenTelemetry Semantic Conventions` plugin analyzes the spans that are part of a trace in order to identify problematic patterns. The set of rules follows the OpenTelemetry conventions to ensure the quality of the telemetry data. - -## Rules - -- [span-naming](../rules/span-naming.md) -- [attribute-naming](../rules/attribute-naming.md) -- [required-attributes](../rules/required-attributes.md) -- [no-empty-attributes](../rules/no-empty-attributes.md) diff --git a/docs/docs/analyzer/plugins/otel-semantic-conventions.mdx b/docs/docs/analyzer/plugins/otel-semantic-conventions.mdx new file mode 100644 index 0000000000..a99629243b --- /dev/null +++ b/docs/docs/analyzer/plugins/otel-semantic-conventions.mdx @@ -0,0 +1,21 @@ +--- +id: otel-semantic-conventions +title: OTel Semantic Conventions +description: The OpenTelemetry Semantic Conventions plugin analyzes spans part of a trace in order to identify problematic patterns. The Tracetest Analyzer analyzes OpenTelemetry traces. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- + +The `OpenTelemetry Semantic Conventions` plugin analyzes the spans that are part of a trace in order to identify problematic patterns. The set of rules follows the OpenTelemetry conventions to ensure the quality of the telemetry data. + +## Rules + +- [span-naming](/analyzer/rules/span-naming) +- [attribute-naming](/analyzer/rules/attribute-naming) +- [required-attributes](/analyzer/rules/required-attributes) +- [no-empty-attributes](/analyzer/rules/no-empty-attributes) diff --git a/docs/docs/analyzer/plugins/security.md b/docs/docs/analyzer/plugins/security.md deleted file mode 100644 index bf66fc8bfe..0000000000 --- a/docs/docs/analyzer/plugins/security.md +++ /dev/null @@ -1,8 +0,0 @@ -# Security - -The `Security` plugin is responsible for analyzing the spans that are part of a trace in order to identify security problems in the distributed system. - -## Rules - -- [secure-https-protocol](../rules/secure-https-protocol.md) -- [no-api-key-leak](../rules/no-api-key-leak.md) diff --git a/docs/docs/analyzer/plugins/security.mdx b/docs/docs/analyzer/plugins/security.mdx new file mode 100644 index 0000000000..4397da305f --- /dev/null +++ b/docs/docs/analyzer/plugins/security.mdx @@ -0,0 +1,19 @@ +--- +id: security +title: Security +description: The Security plugin is responsible for analyzing spans part of a trace to identify security problems. The Tracetest Analyzer analyzes OpenTelemetry traces. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- + +The `Security` plugin is responsible for analyzing the spans that are part of a trace in order to identify security problems in the distributed system. + +## Rules + +- [secure-https-protocol](/analyzer/rules/secure-https-protocol) +- [no-api-key-leak](/analyzer/rules/no-api-key-leak) diff --git a/docs/docs/analyzer/rules/attribute-naming.md b/docs/docs/analyzer/rules/attribute-naming.md deleted file mode 100644 index ca0187d64f..0000000000 --- a/docs/docs/analyzer/rules/attribute-naming.md +++ /dev/null @@ -1,28 +0,0 @@ -# attribute-naming - -Enforce attribute keys to follow common specifications. - -## Rule Details - -An `Attribute` is a key-value pair, which is encapsulated as part of a span. The attribute key should follow a set of common specifications to be considered valid. - -The following OpenTelemetry Semantic Conventions for attribute keys are defined: - -- It must be a non-null and non-empty string. -- It must be a valid Unicode sequence. -- It should use namespacing to avoid name clashes. Delimit the namespaces using a dot character. For example `service.version` denotes the service version where `service` is the namespace and `version` is an attribute in that namespace. -- Namespaces can be nested. For example `telemetry.sdk` is a namespace inside top-level `telemetry` namespace and `telemetry.sdk.name` is an attribute inside `telemetry.sdk` namespace. -- For each multi-word separate the words by underscores (use snake_case). For example `http.status_code` denotes the status code in the http namespace. -- Names should not coincide with namespaces. For example if `service.instance.id` is an attribute name then it is no longer valid to have an attribute named `service.instance` because `service.instance` is already a namespace. - -## Options - -This rule has the following options: - -- `"error"` requires attribute keys to follow the OTel semantic convention -- `"disabled"` disables the attribute keys verification -- `"warning"` verifies attribute keys to follow the OTel semantic convention but does not impact the analyzer score - -## When Not To Use It - -If you don’t want to enforce OTel attribute keys, don’t enable this rule. diff --git a/docs/docs/analyzer/rules/attribute-naming.mdx b/docs/docs/analyzer/rules/attribute-naming.mdx new file mode 100644 index 0000000000..7b73160026 --- /dev/null +++ b/docs/docs/analyzer/rules/attribute-naming.mdx @@ -0,0 +1,39 @@ +--- +id: attribute-naming +title: attribute-naming +description: Enforce attribute keys to follow common specifications | The Tracetest Analyzer analyzes OpenTelemetry traces +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- + +Enforce attribute keys to follow common specifications. + +## Rule Details + +An `Attribute` is a key-value pair, which is encapsulated as part of a span. The attribute key should follow a set of common specifications to be considered valid. + +The following OpenTelemetry Semantic Conventions for attribute keys are defined: + +- It must be a non-null and non-empty string. +- It must be a valid Unicode sequence. +- It should use namespacing to avoid name clashes. Delimit the namespaces using a dot character. For example `service.version` denotes the service version where `service` is the namespace and `version` is an attribute in that namespace. +- Namespaces can be nested. For example `telemetry.sdk` is a namespace inside top-level `telemetry` namespace and `telemetry.sdk.name` is an attribute inside `telemetry.sdk` namespace. +- For each multi-word separate the words by underscores (use snake_case). For example `http.status_code` denotes the status code in the http namespace. +- Names should not coincide with namespaces. For example if `service.instance.id` is an attribute name then it is no longer valid to have an attribute named `service.instance` because `service.instance` is already a namespace. + +## Options + +This rule has the following options: + +- `"error"` requires attribute keys to follow the OTel semantic convention +- `"disabled"` disables the attribute keys verification +- `"warning"` verifies attribute keys to follow the OTel semantic convention but does not impact the analyzer score + +## When Not To Use It + +If you don’t want to enforce OTel attribute keys, don't enable this rule. diff --git a/docs/docs/analyzer/rules/no-api-key-leak.md b/docs/docs/analyzer/rules/no-api-key-leak.mdx similarity index 66% rename from docs/docs/analyzer/rules/no-api-key-leak.md rename to docs/docs/analyzer/rules/no-api-key-leak.mdx index 9f702dc0e1..1b75c304e4 100644 --- a/docs/docs/analyzer/rules/no-api-key-leak.md +++ b/docs/docs/analyzer/rules/no-api-key-leak.mdx @@ -1,4 +1,15 @@ -# no-api-key-leak +--- +id: no-api-key-leak +title: no-api-key-leak +description: Disallow leaked API keys for HTTP spans | The Tracetest Analyzer analyzes OpenTelemetry traces +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Disallow leaked API keys for HTTP spans. diff --git a/docs/docs/analyzer/rules/no-empty-attributes.md b/docs/docs/analyzer/rules/no-empty-attributes.mdx similarity index 60% rename from docs/docs/analyzer/rules/no-empty-attributes.md rename to docs/docs/analyzer/rules/no-empty-attributes.mdx index 981e9f5d3b..cdb2ef8d4d 100644 --- a/docs/docs/analyzer/rules/no-empty-attributes.md +++ b/docs/docs/analyzer/rules/no-empty-attributes.mdx @@ -1,4 +1,15 @@ -# no-empty-attributes +--- +id: no-empty-attributes +title: no-empty-attributes +description: Disallow empty attribute values | The Tracetest Analyzer analyzes OpenTelemetry traces +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Disallow empty attribute values. diff --git a/docs/docs/analyzer/rules/prefer-dns.md b/docs/docs/analyzer/rules/prefer-dns.mdx similarity index 64% rename from docs/docs/analyzer/rules/prefer-dns.md rename to docs/docs/analyzer/rules/prefer-dns.mdx index fab3896184..01ae45b712 100644 --- a/docs/docs/analyzer/rules/prefer-dns.md +++ b/docs/docs/analyzer/rules/prefer-dns.mdx @@ -1,4 +1,15 @@ -# prefer-dns +--- +id: prefer-dns +title: prefer-dns +description: Enforce usage of DNS instead of IP addresses | The Tracetest Analyzer analyzes OpenTelemetry traces +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Enforce usage of DNS instead of IP addresses. @@ -8,14 +19,14 @@ When connecting to remote servers, ensure the usage of DNS instead of IP address The following attributes are evaluated: -``` +```yaml - http.url - db.connection_string ``` If span kind is `"client"`, the following attributes are evaluated: -``` +```yaml - net.peer.name ``` diff --git a/docs/docs/analyzer/rules/required-attributes.md b/docs/docs/analyzer/rules/required-attributes.mdx similarity index 77% rename from docs/docs/analyzer/rules/required-attributes.md rename to docs/docs/analyzer/rules/required-attributes.mdx index d52b2a186d..9fadfcaa2f 100644 --- a/docs/docs/analyzer/rules/required-attributes.md +++ b/docs/docs/analyzer/rules/required-attributes.mdx @@ -1,4 +1,15 @@ -# required-attributes +--- +id: required-attributes +title: required-attributes +description: Enforce required attributes by span type | The Tracetest Analyzer analyzes OpenTelemetry traces +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Enforce required attributes by span type. diff --git a/docs/docs/analyzer/rules/secure-https-protocol.md b/docs/docs/analyzer/rules/secure-https-protocol.mdx similarity index 66% rename from docs/docs/analyzer/rules/secure-https-protocol.md rename to docs/docs/analyzer/rules/secure-https-protocol.mdx index 0e0b0a7861..74c2f0c2c7 100644 --- a/docs/docs/analyzer/rules/secure-https-protocol.md +++ b/docs/docs/analyzer/rules/secure-https-protocol.mdx @@ -1,4 +1,15 @@ -# secure-https-protocol +--- +id: secure-https-protocol +title: secure-https-protocol +description: Enforce usage of secure protocol for HTTP server spans | The Tracetest Analyzer analyzes OpenTelemetry traces +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Enforce usage of secure protocol for HTTP server spans. diff --git a/docs/docs/analyzer/rules/span-naming.md b/docs/docs/analyzer/rules/span-naming.mdx similarity index 53% rename from docs/docs/analyzer/rules/span-naming.md rename to docs/docs/analyzer/rules/span-naming.mdx index e35702c111..dcad29d086 100644 --- a/docs/docs/analyzer/rules/span-naming.md +++ b/docs/docs/analyzer/rules/span-naming.mdx @@ -1,10 +1,21 @@ -# span-naming - -Enforce span names that identify a class of Spans, rather than individual Span instances. +--- +id: span-naming +title: span-naming +description: Enforce span names that identify a class of Spans, rather than individual Span instances | The Tracetest Analyzer analyzes OpenTelemetry traces +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- + +Enforce span names that identify a class of Spans, rather than individual Span instances. ## Rule Details -The span name concisely identifies the work represented by the Span, for example, an RPC method name, a function name, or the name of a subtask or stage within a larger computation. The span name SHOULD be the most general string that identifies a class of Spans, rather than individual Span instances while still being human-readable. +The span name concisely identifies the work represented by the Span, for example, an RPC method name, a function name, or the name of a subtask or stage within a larger computation. The span name SHOULD be the most general string that identifies a class of Spans, rather than individual Span instances while still being human-readable. The following OTel semantic conventions for span names are defined: diff --git a/docs/docs/ci-cd-automation/github-actions-pipeline.md b/docs/docs/ci-cd-automation/github-actions-pipeline.mdx similarity index 97% rename from docs/docs/ci-cd-automation/github-actions-pipeline.md rename to docs/docs/ci-cd-automation/github-actions-pipeline.mdx index 2fd88a4d54..471e64e830 100644 --- a/docs/docs/ci-cd-automation/github-actions-pipeline.md +++ b/docs/docs/ci-cd-automation/github-actions-pipeline.mdx @@ -1,4 +1,15 @@ -# GitHub Actions Pipeline +--- +id: github-actions-pipeline +title: GitHub Actions Pipeline +description: Quick start how to configure GitHub Actions to run Tracetest trace-based tests against a Node.js app with OpenTelemetry instrumentation and traces. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/quick-start-github-actions) diff --git a/docs/docs/ci-cd-automation/overview.md b/docs/docs/ci-cd-automation/overview.mdx similarity index 67% rename from docs/docs/ci-cd-automation/overview.md rename to docs/docs/ci-cd-automation/overview.mdx index e014771104..619df8bfa1 100644 --- a/docs/docs/ci-cd-automation/overview.md +++ b/docs/docs/ci-cd-automation/overview.mdx @@ -1,12 +1,23 @@ -# CI/CD Automation +--- +id: overview +title: CI/CD Automation +description: Overview of running automated trace-based testing with Tracetest in CI/CD pipelines. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- This section contains a general overview of running Tracetest in CI/CD pipelines. You can find guides for: -- [GitHub Actions](./github-actions-pipeline.md) -- [Testkube](./testkube-pipeline.md) -- [Tekton](./tekton-pipeline.md) +- [GitHub Actions](/ci-cd-automation/github-actions-pipeline) +- [Testkube](/ci-cd-automation/testkube-pipeline) +- [Tekton](/ci-cd-automation/tekton-pipeline) :::note If you want to see more examples with other CI/CD tools, let us know by [opening an issue in GitHub](https://github.com/kubeshop/tracetest/issues/new/choose)! @@ -21,7 +32,7 @@ To read more about integrating Tracetest with CI/CD tools, check out tutorials i ## Running Tracetest CLI from Docker -Many integrations with CI/CD tools can be accomplished by running the [Tracetest CLI](../cli/configuring-your-cli.md) to execute a test against a remote Tracetest server. If you do not want to install the Tracetest CLI in your environment, you can choose to directly execute it from a Docker image. +Many integrations with CI/CD tools can be accomplished by running the [Tracetest CLI](../cli/configuring-your-cli) to execute a test against a remote Tracetest server. If you do not want to install the Tracetest CLI in your environment, you can choose to directly execute it from a Docker image. **How to Use**: diff --git a/docs/docs/ci-cd-automation/tekton-pipeline.md b/docs/docs/ci-cd-automation/tekton-pipeline.mdx similarity index 97% rename from docs/docs/ci-cd-automation/tekton-pipeline.md rename to docs/docs/ci-cd-automation/tekton-pipeline.mdx index f1d51af9fe..ebcbd6e2da 100644 --- a/docs/docs/ci-cd-automation/tekton-pipeline.md +++ b/docs/docs/ci-cd-automation/tekton-pipeline.mdx @@ -1,4 +1,15 @@ -# Tekton Cloud-native Pipeline +--- +id: tekton-pipeline +title: Tekton Cloud-native Pipeline +description: Use Tracetest with Tekton to add trace-based testing to Kubernetes-native CI/CD pipelines. Run scheduled and synthetic tests against trace data. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/quick-start-tekton) diff --git a/docs/docs/ci-cd-automation/testkube-pipeline.md b/docs/docs/ci-cd-automation/testkube-pipeline.mdx similarity index 97% rename from docs/docs/ci-cd-automation/testkube-pipeline.md rename to docs/docs/ci-cd-automation/testkube-pipeline.mdx index 170bf3e282..41bb6e3188 100644 --- a/docs/docs/ci-cd-automation/testkube-pipeline.md +++ b/docs/docs/ci-cd-automation/testkube-pipeline.mdx @@ -1,7 +1,18 @@ -# Testkube Kubernetes-native Test Runner Pipeline +--- +id: testkube-pipeline +title: Testkube Kubernetes-native Test Runner Pipeline +description: Use Tracetest with Testkube to add trace-based testing to Kubernetes-native CI/CD pipelines. Run scheduled and synthetic tests against trace data. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note -[Check out how the integration works, here.](../tools-and-integrations/testkube.md) +[Check out how the integration works, here.](/tools-and-integrations/testkube) ::: ## Running Scheduled Trace-based Tests diff --git a/docs/docs/cli/cli-installation-reference.md b/docs/docs/cli/cli-installation-reference.mdx similarity index 84% rename from docs/docs/cli/cli-installation-reference.md rename to docs/docs/cli/cli-installation-reference.mdx index 6065a8a4f3..b9b61599e0 100644 --- a/docs/docs/cli/cli-installation-reference.md +++ b/docs/docs/cli/cli-installation-reference.mdx @@ -1,11 +1,22 @@ -# CLI Installation Reference +--- +id: cli-installation-reference +title: CLI Installation Reference +description: Tracetest adds versions to tests by giving the initial version "v1". When something changes in your test it's detected and the test increases the version by 1. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- This page contains a reference of all options for installing Tracetest CLI. Tracetest has a command line interface (CLI) which includes an **install wizard** that helps to install the Tracetest server into Docker or Kubernetes. The CLI can also be used to run tests, download or upload tests, and manage much of the capability of Tracetest. :::tip Want more info? -Read more about the installation guide [here](../getting-started/installation.mdx). +Read more about the installation guide [here](/getting-started/installation). ::: ## Installing the Tracetest CLI in different operating systems diff --git a/docs/docs/cli/configuring-your-cli.md b/docs/docs/cli/configuring-your-cli.mdx similarity index 84% rename from docs/docs/cli/configuring-your-cli.md rename to docs/docs/cli/configuring-your-cli.mdx index 3a97a6482e..0939a79b8a 100644 --- a/docs/docs/cli/configuring-your-cli.md +++ b/docs/docs/cli/configuring-your-cli.mdx @@ -1,4 +1,15 @@ -# Configuring your CLI +--- +id: configuring-your-cli +title: Configuring your CLI +description: Configure the Tracetest CLI. The CLI is used for creating tests and executing them each time a change is made in the system. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Our web interface makes it easier to visualize your traces and add assertions, but sometimes a CLI is needed for automation. The CLI was developed for users creating tests and executing them each time a change is made in the system, so Tracetest can detect regressions and check your Service Level Objectives (SLOs). diff --git a/docs/docs/cli/creating-data-stores.md b/docs/docs/cli/creating-data-stores.mdx similarity index 79% rename from docs/docs/cli/creating-data-stores.md rename to docs/docs/cli/creating-data-stores.mdx index b0db55ef55..592bd846df 100644 --- a/docs/docs/cli/creating-data-stores.md +++ b/docs/docs/cli/creating-data-stores.mdx @@ -1,4 +1,15 @@ -# Defining Data Stores as Text Files +--- +id: creating-data-stores +title: Defining Data Stores as Text Files +description: Configure Trace Data Stores in Tracetest by using a configuration file that can be applied to your Tracetest instance. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- You might have multiple Tracetest instances that need to be connected to the same data stores. An easy way of sharing the configuration is by using a configuration file that can be applied to your Tracetest instance. @@ -151,11 +162,11 @@ spec: default: true ``` -> Consider reading about [how to use the OTEL collector](../configuration/connecting-to-data-stores/opentelemetry-collector.md) to send traces to your Tracetest instance. +> Consider reading about [how to use the OTEL collector](/configuration/connecting-to-data-stores/opentelemetry-collector) to send traces to your Tracetest instance. ## Apply Configuration -To apply the configuration, you need a [configured CLI](./configuring-your-cli.md) pointed to the instance you want to apply the data store. Then use the following command: +To apply the configuration, you need a [configured CLI](/cli/configuring-your-cli) pointed to the instance you want to apply the data store. Then use the following command: ``` tracetest apply datastore -f my/data-store/file/location.yaml diff --git a/docs/docs/cli/creating-test-outputs.md b/docs/docs/cli/creating-test-outputs.mdx similarity index 71% rename from docs/docs/cli/creating-test-outputs.md rename to docs/docs/cli/creating-test-outputs.mdx index 854fc14a43..3156ec7816 100644 --- a/docs/docs/cli/creating-test-outputs.md +++ b/docs/docs/cli/creating-test-outputs.mdx @@ -1,10 +1,21 @@ -# Defining Test Outputs in Text Files - -Outputs are really useful when running [Test Suites](../concepts/test-suites). They allow for exporting values from a test so they become available in the [Variable Sets](../concepts/variable-sets.md) of the current Test Suite. +--- +id: creating-test-outputs +title: Defining Test Outputs in Text Files +description: Test outputs allow for exporting values from a test so they become available in Variable Sets of a Test Suite. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- + +Outputs are really useful when running [Test Suites](/concepts/test-suites). They allow for exporting values from a test so they become available in the [Variable Sets](/concepts/variable-sets) of the current Test Suite. ## Outputs are Expression Results -An output exports the result of an [Expression](../concepts/expressions) and assigns it to a name, so it can be injected into the variable set of a running Test Suite. +An output exports the result of an [Expression](/concepts/expressions) and assigns it to a name, so it can be injected into the variable set of a running Test Suite. A `selector` is needed only if the provided expression refers to a/some span/s attribute or meta attributes. It can be defined using the following YAML definition: diff --git a/docs/docs/cli/creating-test-specifications.md b/docs/docs/cli/creating-test-specifications.mdx similarity index 90% rename from docs/docs/cli/creating-test-specifications.md rename to docs/docs/cli/creating-test-specifications.mdx index 39806ffa3f..5efda42a59 100644 --- a/docs/docs/cli/creating-test-specifications.md +++ b/docs/docs/cli/creating-test-specifications.mdx @@ -1,4 +1,15 @@ -# Defining Test Specifications in Text Files +--- +id: creating-test-specifications +title: Defining Test Specifications in Text Files +description: Test Specifications may be added to a trace to set a value for a step in the trace to determine success or failure. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Test Specifications may be added to a trace to set a value for a step in the trace to determine success or failure. @@ -8,8 +19,8 @@ Assertions are as important as how you trigger your test. Without them, your tes Before we start, there are two concepts that you must understand to write your tests: -- [Selectors](../concepts/selectors.md) -- [Assertions](../concepts/assertions.md) +- [Selectors](/concepts/selectors) +- [Assertions](/concepts/assertions) ### Selectors diff --git a/docs/docs/cli/creating-test-suites.md b/docs/docs/cli/creating-test-suites.mdx similarity index 62% rename from docs/docs/cli/creating-test-suites.md rename to docs/docs/cli/creating-test-suites.mdx index 38c1fc2d6c..f9798cde90 100644 --- a/docs/docs/cli/creating-test-suites.md +++ b/docs/docs/cli/creating-test-suites.mdx @@ -1,9 +1,20 @@ -# Defining Test Suites as Text Files +--- +id: creating-test-suites +title: Defining Test Suites as Text Files +description: Create and edit Test Suites with the CLI. Just like other structures of Tracetest, you can also manage your Test Suites using the CLI and definition files. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- This page showcases how to create and edit Test Suites with the CLI. :::tip -[To read more about Test Suites check out Test Suites concepts page.](../concepts/test-suites.md) +[To read more about Test Suites check out Test Suites concepts page.](/concepts/test-suites) ::: Just like other structures of Tracetest, you can also manage your Test Suites using the CLI and definition files. @@ -22,7 +33,7 @@ spec: - testID # you can also reference tests by their ids instead of referencing the definition file ``` -In order to apply this Test Suite to your Tracetest instance, make sure to have your [CLI configured](./configuring-your-cli.md) and run: +In order to apply this Test Suite to your Tracetest instance, make sure to have your [CLI configured](/cli/configuring-your-cli) and run: ```sh tracetest apply testsuite -f diff --git a/docs/docs/cli/creating-tests.md b/docs/docs/cli/creating-tests.mdx similarity index 93% rename from docs/docs/cli/creating-tests.md rename to docs/docs/cli/creating-tests.mdx index 5e57135e9e..fc07fe87c0 100644 --- a/docs/docs/cli/creating-tests.md +++ b/docs/docs/cli/creating-tests.mdx @@ -1,4 +1,15 @@ -# Defining Tests as Text Files +--- +id: creating-tests +title: Defining Tests as Text Files +description: Tracetest enables developers to define tests as text files and run them using a CLI. Integrate the execution of tests in your existing CI pipeline. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- One important aspect of testing your code is the ability to quickly implement changes while not breaking your application. If you change your application, it is important to be able to update your tests and run them against your new implementation as soon as possible for a timely development feedback loop. @@ -171,9 +182,9 @@ Available functions: | `randomInt(min, max)` | Generates a random integer contained in the closed interval defined by [`min`, `max`]. | :::tip -[Continue reading about Test Specs, here.](./creating-test-specifications.md) +[Continue reading about Test Specs, here.](/cli/creating-test-specifications) ::: :::tip -[Continue reading about Test Outputs, here.](./creating-test-outputs.md) +[Continue reading about Test Outputs, here.](/cli/creating-test-outputs) ::: diff --git a/docs/docs/cli/creating-variable-sets.md b/docs/docs/cli/creating-variable-sets.mdx similarity index 66% rename from docs/docs/cli/creating-variable-sets.md rename to docs/docs/cli/creating-variable-sets.mdx index 783883734e..d0fc669815 100644 --- a/docs/docs/cli/creating-variable-sets.md +++ b/docs/docs/cli/creating-variable-sets.mdx @@ -1,9 +1,20 @@ -# Defining Variable Sets as Text Files +--- +id: creating-variable-sets +title: Defining Variable Sets as Text Files +description: Configure Variable Sets in Tracetest by using a configuration file that can be applied to your Tracetest instance. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- This page showcases how to create and edit variable sets with the CLI. :::tip -[To read more about variable sets check out variable sets concepts.](../concepts/variable-sets.md) +[To read more about variable sets check out variable sets concepts.](/concepts/variable-sets) ::: Just like Data Stores, you can also manage your variable sets using the CLI and definition files. @@ -22,7 +33,7 @@ spec: value: mysecret ``` -In order to apply this configuration to your Tracetest instance, make sure to have your [CLI configured](./configuring-your-cli.md) and run: +In order to apply this configuration to your Tracetest instance, make sure to have your [CLI configured](/cli/configuring-your-cli) and run: ```sh tracetest apply variableset -f diff --git a/docs/docs/cli/exporting-tests.md b/docs/docs/cli/exporting-tests.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/docs/cli/running-test-suites.md b/docs/docs/cli/running-test-suites.mdx similarity index 79% rename from docs/docs/cli/running-test-suites.md rename to docs/docs/cli/running-test-suites.mdx index 6b6d016140..44862f8c8d 100644 --- a/docs/docs/cli/running-test-suites.md +++ b/docs/docs/cli/running-test-suites.mdx @@ -1,4 +1,15 @@ -# Running Test Suites From the Command Line Interface (CLI) +--- +id: running-test-suites +title: Running Test Suites From the Command Line Interface (CLI) +description: Run Tracetest Test Suites from the Command Line Interface (CLI) to integrate it into your CI/CD process or your local development workflow. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Once you have created a Test Suite, whether from the Tracetest UI or via a text editor, you will need the capability to run it via the Command Line Interface (CLI) to integrate it into your CI/CD process or your local development workflow. @@ -6,7 +17,7 @@ The command to run a Test Suite is the same as running a test from the CLI. The documentation for running a test via the CLI can be found here: -- [tracetest run](./reference/tracetest_run.md): This page provides examples of using this command. +- [tracetest run](/cli/reference/tracetest_run): This page provides examples of using this command. ## Running Your First Test Suite diff --git a/docs/docs/cli/running-tests.md b/docs/docs/cli/running-tests.mdx similarity index 93% rename from docs/docs/cli/running-tests.md rename to docs/docs/cli/running-tests.mdx index 276ddd2a21..aff1e9e4df 100644 --- a/docs/docs/cli/running-tests.md +++ b/docs/docs/cli/running-tests.mdx @@ -1,10 +1,21 @@ -# Running Tests From the Command Line Interface (CLI) +--- +id: running-tests +title: Running Tests From the Command Line Interface (CLI) +description: Run Tracetest Tests from the Command Line Interface (CLI) to integrate it into your CI/CD process or your local development workflow. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Once you have created a test, whether from the Tracetest UI or via a text editor, you will need the capability to run it via the Command Line Interface (CLI) to integrate it into your CI/CD process or your local development workflow. The documentation for running a test via the CLI can be found here: -- [tracetest run](./reference/tracetest_run.md): This page provides examples of using this command. +- [tracetest run](/cli/reference/tracetest_run): This page provides examples of using this command. ## Running Your First Test diff --git a/docs/docs/cli/undefined-variables.md b/docs/docs/cli/undefined-variables.mdx similarity index 69% rename from docs/docs/cli/undefined-variables.md rename to docs/docs/cli/undefined-variables.mdx index eb1eec369d..1de8fe51b9 100644 --- a/docs/docs/cli/undefined-variables.md +++ b/docs/docs/cli/undefined-variables.mdx @@ -1,4 +1,15 @@ -# Undefined Variables +--- +id: undefined-variables +title: Undefined Variables +description: When variables from a Variable Set are undefined and you run a Test or Test Suite, any variables that are needed will be prompted for. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- When a user runs a test or a Test Suite, any variables that will be needed but are not defined will be prompted for: @@ -52,5 +63,5 @@ tracetest run test -f path/to/test.yaml --vars testvars ``` :::tip -[Check out use-cases for using undefined variables here.](../concepts/ad-hoc-testing.md) +[Check out use-cases for using undefined variables here.](/concepts/ad-hoc-testing) ::: diff --git a/docs/docs/concepts/ad-hoc-testing.md b/docs/docs/concepts/ad-hoc-testing.mdx similarity index 82% rename from docs/docs/concepts/ad-hoc-testing.md rename to docs/docs/concepts/ad-hoc-testing.mdx index 70ee6f801a..fe40038fb2 100644 --- a/docs/docs/concepts/ad-hoc-testing.md +++ b/docs/docs/concepts/ad-hoc-testing.mdx @@ -1,13 +1,24 @@ -# Ad-hoc Testing +--- +id: ad-hoc-testing +title: Ad-hoc Testing +description: Use Tracetest to enable ad-hoc testing by utilizing variable sets and undefined variables. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- This page showcases use-cases for undefined variables and how to enable ad-hoc testing by utilizing variable sets and undefined variables. :::tip -[Check out how to configure ad-hoc testing with undefined variables with the **Web UI** here.](../web-ui/undefined-variables.md) +[Check out how to configure ad-hoc testing with undefined variables with the **Web UI** here.](../web-ui/undefined-variables) ::: :::tip -[Check out how to configure ad-hoc testing with undefined variables with the **CLI** here.](../cli/undefined-variables.md) +[Check out how to configure ad-hoc testing with undefined variables with the **CLI** here.](../cli/undefined-variables) ::: ## **Undefined Variables Use Cases** diff --git a/docs/docs/concepts/agent.mdx b/docs/docs/concepts/agent.mdx index 868916175f..c3a677b9bc 100644 --- a/docs/docs/concepts/agent.mdx +++ b/docs/docs/concepts/agent.mdx @@ -1,14 +1,14 @@ --- id: agent title: Tracetest Agent -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. +description: Tracetest Agent is a lightweight, dependency-free agent that runs locally in your development environment, or as a Docker container in your Cloud Native infrastructure. keywords: - tracetest - trace-based testing - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- Tracetest Agent is a lightweight, dependency-free agent that runs locally in your development environment, or as a Docker container in your Cloud Native infrastructure. diff --git a/docs/docs/concepts/architecture.md b/docs/docs/concepts/architecture.md deleted file mode 100644 index 331aaa72f6..0000000000 --- a/docs/docs/concepts/architecture.md +++ /dev/null @@ -1,5 +0,0 @@ -# Architecture - -The diagram below shows the underlying Tracetest architecture. - -![Architecture Diagram](../img/creatingatestdiagram.gif) diff --git a/docs/docs/concepts/architecture.mdx b/docs/docs/concepts/architecture.mdx new file mode 100644 index 0000000000..d7709e9657 --- /dev/null +++ b/docs/docs/concepts/architecture.mdx @@ -0,0 +1,16 @@ +--- +id: architecture +title: Architecture +description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- + +The diagram below shows the underlying Tracetest architecture. + +![Architecture Diagram](../img/creatingatestdiagram.gif) diff --git a/docs/docs/concepts/assertions.md b/docs/docs/concepts/assertions.mdx similarity index 82% rename from docs/docs/concepts/assertions.md rename to docs/docs/concepts/assertions.mdx index ff7b2bf2de..8eee954a57 100644 --- a/docs/docs/concepts/assertions.md +++ b/docs/docs/concepts/assertions.mdx @@ -1,4 +1,15 @@ -# Assertions +--- +id: assertions +title: Assertions +description: Assertions are added to set a value for a step in the trace to determine success or failure. Build integration and end-to-end tests with OpenTelemetry traces with Tracetest. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Test Specifications may be added to a trace to set a value for a step in the trace to determine success or failure. If test specs have already been added to a test, they will be on the Test screen: diff --git a/docs/docs/concepts/data-stores.md b/docs/docs/concepts/data-stores.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/docs/concepts/environments.mdx b/docs/docs/concepts/environments.mdx index ef598a2f3b..829ee1116c 100644 --- a/docs/docs/concepts/environments.mdx +++ b/docs/docs/concepts/environments.mdx @@ -1,7 +1,7 @@ --- id: environments title: Environments -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. +description: Environments are workspaces where you keep tests, test suites, variable sets, and all other Tracetest resources. Build integration and end-to-end tests with OpenTelemetry traces with Tracetest. hide_table_of_contents: false keywords: - tracetest @@ -9,7 +9,7 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- Environments are workspaces where you keep tests, test suites, variable sets, and all other Tracetest resources. diff --git a/docs/docs/concepts/expressions.md b/docs/docs/concepts/expressions.mdx similarity index 86% rename from docs/docs/concepts/expressions.md rename to docs/docs/concepts/expressions.mdx index c310b09d8a..27e0f21c20 100644 --- a/docs/docs/concepts/expressions.md +++ b/docs/docs/concepts/expressions.mdx @@ -1,8 +1,20 @@ -# Expressions +--- +id: expressions +title: Expressions +description: Expressions are used to add values that are only known during execution time. Build integration and end-to-end tests with OpenTelemetry traces with Tracetest. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Tracetest allows you to add expressions when writing your tests. They are a nice and clean way of adding values that are only known during execution time. For example, when referencing a variable, a span attribute or even arithmetic operations. -## **Features** +## Features * Reference span attributes * Reference variables @@ -10,7 +22,7 @@ Tracetest allows you to add expressions when writing your tests. They are a nice * String interpolation * Filters -### **Reference Span Attributes** +### Reference Span Attributes When building assertions, you might need to assert if a certain span contains an attribute and that this attribute has a specific value. To accomplish this with Tracetest, you can use expressions to get the value of the span. When referencing an attribute, add the prefix `attr:` and its name. For example, imagine you have to check if the attribute `service.name` is equal to `cart-api`. Use the following statement: @@ -18,11 +30,11 @@ When building assertions, you might need to assert if a certain span contains an attr:service.name = "cart-api" ``` -### **Reference Variables** +### Reference Variables Create variables in Tracetest based on the trace obtained by the test to enable assertions that require values from other spans. Variables use the prefix `var:` and its name. For example, a variable called `user_id` would be referenced as `var:user_id` in an expression. -### **Arithmetic Operations** +### Arithmetic Operations Sometimes we need to manipulate data to ensure our test data is correct. As an example, we will use a purchase operation. How you would make sure that, after the purchase, the product inventory is smaller than before? For this, we might want to use arithmetic operations: @@ -30,7 +42,7 @@ Sometimes we need to manipulate data to ensure our test data is correct. As an e attr:product.stock = attr:product.stok_before_purchase - attr:product.number_bought_items ``` -### **String Interpolation** +### String Interpolation Some tests might require strings to be compared, but maybe you need to generate a dynamic string that relies on a dynamic value. This might be used in an assertion or even in the request body referencing a variable. @@ -40,12 +52,11 @@ attr:error.message = "Could not withdraw ${attr:withdraw.amount}, your balance i Note that within `${}` you can add any expression, including arithmetic operations and filters. - -### **Filters** +### Filters Filters are functions that are executed using the value obtained by the expression. They are useful to transform the data. Multiple filters can be chained together. The output of the previous filter will be used as the input to the next until all filters are executed. -#### **JSON Path** +#### JSON Path This filter allows you to filter a JSON string and obtain only data that is relevant. ```css @@ -58,14 +69,14 @@ If multiple values are matched, the output will be a flat array containing all v '{ "array": [{"name": "Jorge", "age": 27}, {"name": "Tim", "age": 52}]}' | json_path '$.array[*]..["name", "age"] = '["Jorge", 27, "Tim", 52]' ``` -#### **RegEx** +#### RegEx Filters part of the input that match a RegEx. Imagine you have a specific part of a text that you want to extract: ```css 'My account balance is $48.52' | regex '\$\d+(\.\d+)?' = '$48.52' ``` -#### **RegEx Group** +#### RegEx Group If matching more than one value is required, you can define groups for your RegEx and extract multiple values at once. Wrap the groups you want to extract with parentheses. @@ -74,7 +85,7 @@ Wrap the groups you want to extract with parentheses. 'Hello Marcus, today you have 8 meetings' | regex_group 'Hello (\w+), today you have (\d+) meetings' = '["Marcus", 8]' ``` -### **Get Index** +### Get Index Some filters might result in an array. If you want to assert just part of this array, this filter allows you to pick one element from the array based on its index. @@ -88,7 +99,7 @@ You can select the last item from a list by specifying `'last'` as the argument '{ "array": [1, 2, 3] }' | json_path '$.array[*]' | get_index 'last' = 3 ``` -### **Length** +### Length Returns the size of the input array. If it's a single value, it will return 1. Otherwise it will return `length(input_array)`. @@ -100,7 +111,7 @@ Returns the size of the input array. If it's a single value, it will return 1. O "my string" | length = 1 ``` -### **Type** +### Type Return the type of the input as a string. diff --git a/docs/docs/concepts/organizations.mdx b/docs/docs/concepts/organizations.mdx index 0fc28fbe63..961b3e6105 100644 --- a/docs/docs/concepts/organizations.mdx +++ b/docs/docs/concepts/organizations.mdx @@ -9,7 +9,7 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- Organizations contain a collection of environments, team members, and settings. diff --git a/docs/docs/concepts/selectors.md b/docs/docs/concepts/selectors.mdx similarity index 98% rename from docs/docs/concepts/selectors.md rename to docs/docs/concepts/selectors.mdx index 85da417140..a7d97d7d4e 100644 --- a/docs/docs/concepts/selectors.md +++ b/docs/docs/concepts/selectors.mdx @@ -1,4 +1,16 @@ -# Selectors +--- +id: selectors +title: Selectors +description: Advanced selectors enable selecting spans for assertions. Build integration and end-to-end tests with OpenTelemetry traces with Tracetest. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- If you find yourself in a position where you cannot select complex spans, you can use our advanced selectors to help with that task. Advanced selectors enable selecting spans that are impossible to select using just basic selectors. diff --git a/docs/docs/concepts/test-suites.md b/docs/docs/concepts/test-suites.mdx similarity index 77% rename from docs/docs/concepts/test-suites.md rename to docs/docs/concepts/test-suites.mdx index 6bd655a168..2e43fb043b 100644 --- a/docs/docs/concepts/test-suites.md +++ b/docs/docs/concepts/test-suites.mdx @@ -1,4 +1,15 @@ -# Test Suites +--- +id: test-suites +title: Test Suites +description: Use Tracetest to enable ad-hoc testing by utilizing variable sets and undefined variables. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Most End-to-End tests are not simple to run. They require some setup before the actual test is run. Actions like creating a new user, removing all items from a cart, etc. It is important that you can execute multiple steps as part of your Test Suite. Tracetest introduces the concept of **Test Suites** to achieve this goal. @@ -9,18 +20,18 @@ A Test Suite is defined as a group of steps that are executed in the defined ord The main benefit of using Test Suites is to chain tests together and use values obtained from a test in a subsequent test. ### How Values are Shared by Tests -When a Test Suite is run, a context object is created with information about that specific run. One of those pieces of information is a `variable set` object, which is empty by default. If the Test Suite is run when referencing an [variable set](./variable-sets.md), all values from the selected variable sets will be copied to the `variable set` object. +When a Test Suite is run, a context object is created with information about that specific run. One of those pieces of information is a `variable set` object, which is empty by default. If the Test Suite is run when referencing an [variable set](/concepts/variable-sets), all values from the selected variable sets will be copied to the `variable set` object. When a test is executed within a Test Suite, if it generates any outputs, its outputs will be injected into the Test Suite context variable set object. After the outputs are injected, all subsequent tests to be run within the Test Suite will be able to reference those values. -> :information_source: Outputs generated by steps don't modify the selected [variable set](./variable-sets.md). It only modifies the Test Suite run context object. +> :information_source: Outputs generated by steps don't modify the selected [variable set](/concepts/variable-sets). It only modifies the Test Suite run context object. Consider you have 3 tests within a Test Suite: A, B, and C. Tests A and B generate outputs called A_OUTPUT and B_OUTPUT, respectively. When running the Test Suite, we provide a variable set which contains a `HOST` variable. The execution of test A would only be able to reference `var:HOST`. B would be able to reference `var:HOST`, and `var:A_OUTPUT`. While C would be able to reference all three variables: `var:HOST`, `var:A_OUTPUT`, `var:B_OUTPUT`. > :information_source: A single test can contain as many outputs as you like. ### Exposing Values from a Test to Other Tests -Since version v0.8, Tracetest allows tests to declare `outputs`. An output is a value that is extracted from a trace by providing a [selector](./selectors) to choose which spans to use to get the information from, and an [expression](./expressions) to get the value from the selected spans. For example, consider that you want to expose the time a specific job was taken from a queue and began executing. An output would look something like the following: +Since version v0.8, Tracetest allows tests to declare `outputs`. An output is a value that is extracted from a trace by providing a [selector](/concepts/selectors) to choose which spans to use to get the information from, and an [expression](/concepts/expressions) to get the value from the selected spans. For example, consider that you want to expose the time a specific job was taken from a queue and began executing. An output would look something like the following: ```yaml outputs: diff --git a/docs/docs/concepts/tests.md b/docs/docs/concepts/tests.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/docs/concepts/variable-sets.md b/docs/docs/concepts/variable-sets.mdx similarity index 85% rename from docs/docs/concepts/variable-sets.md rename to docs/docs/concepts/variable-sets.mdx index f5ffee3f49..f8e9ded38b 100644 --- a/docs/docs/concepts/variable-sets.md +++ b/docs/docs/concepts/variable-sets.mdx @@ -1,4 +1,15 @@ -# Variable Sets +--- +id: variable-sets +title: Variable Sets +description: Use Tracetest to enable ad-hoc testing by utilizing variable sets and undefined variables. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- A common use case for tests is to assert the same behavior across multiple environments (dev, staging, and production, for example). To make sure all of these environments will have the same behavior, it is important that the tests executed against those environments test the same aspects. To reduce the risks of diverging tests, Tracetest allows you to organize different environments configurations using global objects called **Variable Sets**. diff --git a/docs/docs/concepts/versioning.md b/docs/docs/concepts/versioning.mdx similarity index 74% rename from docs/docs/concepts/versioning.md rename to docs/docs/concepts/versioning.mdx index 59f34c0fcd..039556258c 100644 --- a/docs/docs/concepts/versioning.md +++ b/docs/docs/concepts/versioning.mdx @@ -1,14 +1,25 @@ -# Versioning +--- +id: versioning +title: Versioning +description: Tracetest adds versions to tests by giving the initial version "v1". When something changes in your test it's detected and the test increases the version by 1. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- As your system evolves, your tests tend to do the same. However, that might be confusing if you don't have a versioning mechanism in place. Imagine that you wrote a new test for the version `v0.5.0` of your application. After some months, your application is in version `v0.13.7`. Most likely, your tests changed as you moved your application forward. But without versioning, if you revisit that first test you created, it will look like exactly the one you use today instead of the test you originally wrote. That happens because while you have multiple versions of your application, you only keep track of one version of your tests: the current version. So there is no way to go back in time and see what a test looked like in the past. **But that is not a problem if you use Tracetest. It has versioning built-in!** -## **How It Works** +## How It Works Once you create a test, it is tagged as the initial version (`v1`). Every time you change something in your test (edit its identification details, add assertions, change selectors, etc), Tracetest detects those changes and increases the version by 1. If no changes were made, the version is kept untouched. -### **Change Detection** +### Change Detection These are the fields of a test that are checked to verify if it has changed: @@ -20,6 +31,6 @@ These are the fields of a test that are checked to verify if it has changed: - assertions - test outputs -### **Problems** +### Problems If you notice you are editing fields and your test version is not changing, let us know by opening a [bug report](https://github.com/kubeshop/tracetest/issues) on our Github Repository. diff --git a/docs/docs/concepts/what-is-trace-based-testing.md b/docs/docs/concepts/what-is-trace-based-testing.mdx similarity index 72% rename from docs/docs/concepts/what-is-trace-based-testing.md rename to docs/docs/concepts/what-is-trace-based-testing.mdx index 3ccc545efe..1ff2ad89b2 100644 --- a/docs/docs/concepts/what-is-trace-based-testing.md +++ b/docs/docs/concepts/what-is-trace-based-testing.mdx @@ -1,10 +1,19 @@ -# What is Trace-Based Testing - - -Trace-Based Testing is a means of conducting deep integration or system tests by utilizing the rich data contained in a distributed system trace. - - -## **What is a Distributed Trace?** +--- +id: what-is-trace-based-testing +title: What is Trace-Based Testing +description: Trace-based testing is a means of conducting deep integration or system tests by utilizing the rich data contained in a distributed system trace. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- + +**Trace-based testing** is a means of conducting deep integration or system tests by utilizing the rich data contained in a distributed system trace. + +## What is a Distributed Trace? A Distributed Trace, more commonly known as a Trace, records the paths taken by requests (made by an application or end-user) take as they propagate through multi-service architectures, like microservice and serverless applications. [Source - OpenTelemetry.io](https://opentelemetry.io/docs/concepts/observability-primer/) @@ -12,55 +21,41 @@ In Tracetest, after selecting a test from the first screen and clicking on the * ![Trace Example](../img/trace-example.png) - - - -### **What is a Span?** +### What is a Span? Traces are comprised of spans. A span represents a single operation in a trace. Spans are nested, typically with a parent child relationship to form a deeply nested tree. ![Span Example](../img/span-example.png) -### **What Data do Spans Contain?** - +### What Data do Spans Contain? A span contains the data about the operation it represents. This data includes: - The span name. - - Start and end timestamp. - - List of events (if instrumented). - - Attributes -### **What are Attributes?** +### What are Attributes? Attributes are a key-value pair, and they contain information about the operation. A developer can manually add additional attributes to a span, enriching the data. There are [Semantic Conventions](https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/) that provide recommended names for the attributes for common types of calls such as database, http, messaging, etc. -## **What is a Test Spec?** - +## What is a Test Spec? In Tracetest, a Test Spec is comprised of two parts: - - Selectors - Checks - - -### **What is a Selector?** - +### What is a Selector? A selector contains criteria to limit the scope of the spans from a trace that we wish to assert against. A selector can be very narrow, only selecting on one span, or very wide, selecting all spans or all spans of a certain type or other characteristics. Underlying this capability is a [selector language](./selectors). -### **What is a Check?** - +### What is a Check? A check is a logical verification that will be performed on all spans that match the selector. It is comprised of an attribute, a comparison operator and a value. -### **What is a Span Signature?** - +### What is a Span Signature? A span signature is an automatically computed selector that has enough elements to specify a single span. It uses a combination of attributes in the selected span to automatically build the selector. If a trace has multiple spans that are almost identical, the span signature may still match more than one span. You can alter the selector in this case to be more specific by adding other attributes or specifying an ancestor span. diff --git a/docs/docs/concepts/what-is-tracing.md b/docs/docs/concepts/what-is-tracing.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/docs/configuration/agent.mdx b/docs/docs/configuration/agent.mdx index 8bde8707b5..566f639b18 100644 --- a/docs/docs/configuration/agent.mdx +++ b/docs/docs/configuration/agent.mdx @@ -8,7 +8,7 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- Tracetest Agent is a lightweight, dependency-free, agent that runs locally in your development environment, or as a Docker container in your Cloud Native infrastructure. diff --git a/docs/docs/configuration/config-file-reference.md b/docs/docs/configuration/config-file-reference.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/docs/configuration/connecting-to-data-stores/awsxray.md b/docs/docs/configuration/connecting-to-data-stores/awsxray.mdx similarity index 75% rename from docs/docs/configuration/connecting-to-data-stores/awsxray.md rename to docs/docs/configuration/connecting-to-data-stores/awsxray.mdx index ea9f959582..b41717f417 100644 --- a/docs/docs/configuration/connecting-to-data-stores/awsxray.md +++ b/docs/docs/configuration/connecting-to-data-stores/awsxray.mdx @@ -1,4 +1,15 @@ -# AWS X-Ray +--- +id: awsxray +title: AWS X-Ray +description: Use AWS X-Ray as the trace data store for Tracetest. You can use the native connection from Tracetest to pull telemetry data directly from any region. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- If you want to use [AWS X-Ray](https://aws.amazon.com/xray/) as the trace data store, you can use the native connection from Tracetest to pull telemetry data directly from any region. @@ -13,7 +24,7 @@ Configure Tracetest to be aware that it has to fetch trace data from X-Ray. Tracetest uses the Golang [AWS-SDK](https://aws.amazon.com/sdk-for-go/) library to pull to fetch trace data. :::tip -Need help configuring the OpenTelemetry Collector so send trace data from your application to AWS X-Ray? Read more in [the reference page here](../opentelemetry-collector-configuration-file-reference). +Need help configuring the OpenTelemetry Collector so send trace data from your application to AWS X-Ray? Read more in [the reference page here](/configuration/opentelemetry-collector-configuration-file-reference). ::: ## Connect Tracetest to X-Ray with the Web UI @@ -49,5 +60,5 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe on running a sample app with AWS X-Ray and Tracetest](../../examples-tutorials/recipes/running-tracetest-with-aws-x-ray.md). +To learn more, [read the recipe on running a sample app with AWS X-Ray and Tracetest](/examples-tutorials/recipes/running-tracetest-with-aws-x-ray). ::: diff --git a/docs/docs/configuration/connecting-to-data-stores/azure-app-insights.md b/docs/docs/configuration/connecting-to-data-stores/azure-app-insights.mdx similarity index 81% rename from docs/docs/configuration/connecting-to-data-stores/azure-app-insights.md rename to docs/docs/configuration/connecting-to-data-stores/azure-app-insights.mdx index 11df3f016a..d53f94701b 100644 --- a/docs/docs/configuration/connecting-to-data-stores/azure-app-insights.md +++ b/docs/docs/configuration/connecting-to-data-stores/azure-app-insights.mdx @@ -1,4 +1,15 @@ -# Azure App Insights +--- +id: azure-app-insights +title: Azure App Insights +description: Use Azure App Insights as the trace data store for Tracetest. You can use the native connection from Tracetest to pull telemetry data directly from any region. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- If you want to use [Azure App Insights](https://learn.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview) as the trace data store, you can use the native connection from Tracetest to pull telemetry data. @@ -46,7 +57,7 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe on running a sample app with Azure App Insights and Tracetest](../../examples-tutorials/recipes/running-tracetest-with-azure-app-insights). +To learn more, [read the recipe on running a sample app with Azure App Insights and Tracetest](/examples-tutorials/recipes/running-tracetest-with-azure-app-insights). ::: ## OpenTelemetry Collector @@ -54,7 +65,7 @@ To learn more, [read the recipe on running a sample app with Azure App Insights You can configure Tracetest to listen for incoming telemetry data from ports `4317` and `4318` for gRPC and REST accordingly, giving you the option to stream the information to both Azure App Insights and Tracetest at the same time. :::tip -Need help configuring the [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector-contrib) to send trace data from your application to Azure App Insights? Read more in [the reference page here](../opentelemetry-collector-configuration-file-reference). +Need help configuring the [OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector-contrib) to send trace data from your application to Azure App Insights? Read more in [the reference page here](/configuration/opentelemetry-collector-configuration-file-reference). ::: ### Tracetest OpenTelemetry Collector connection to Azure App Insights with the Web UI @@ -87,5 +98,5 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe on running a sample app with Azure App Insights, The OpenTelemetry Collector and Tracetest](../../examples-tutorials/recipes/running-tracetest-with-azure-app-insights-collector.md). +To learn more, [read the recipe on running a sample app with Azure App Insights, The OpenTelemetry Collector and Tracetest](/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-collector). ::: diff --git a/docs/docs/configuration/connecting-to-data-stores/datadog.md b/docs/docs/configuration/connecting-to-data-stores/datadog.mdx similarity index 86% rename from docs/docs/configuration/connecting-to-data-stores/datadog.md rename to docs/docs/configuration/connecting-to-data-stores/datadog.mdx index dac4e80d20..28be5ee1af 100644 --- a/docs/docs/configuration/connecting-to-data-stores/datadog.md +++ b/docs/docs/configuration/connecting-to-data-stores/datadog.mdx @@ -1,4 +1,15 @@ -# Datadog +--- +id: datadog +title: Datadog +description: Use Datadog as the trace data store for Tracetest. Configure the OpenTelemetry Collector to receive traces and forward them to both Tracetest and Datadog. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- If you want to use [Datadog](https://www.datadoghq.com/) as the trace data store, you'll configure the OpenTelemetry Collector to receive traces from your system and then send them to both Tracetest and Datadog. And, you don't have to change your existing pipelines to do so. @@ -100,5 +111,5 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe for running a sample app with Datadog and Tracetest](../../examples-tutorials/recipes/running-tracetest-with-datadog.md). +To learn more, [read the recipe for running a sample app with Datadog and Tracetest](/examples-tutorials/recipes/running-tracetest-with-datadog). ::: diff --git a/docs/docs/configuration/connecting-to-data-stores/dynatrace.md b/docs/docs/configuration/connecting-to-data-stores/dynatrace.mdx similarity index 88% rename from docs/docs/configuration/connecting-to-data-stores/dynatrace.md rename to docs/docs/configuration/connecting-to-data-stores/dynatrace.mdx index 59ab3af9c2..23b7f8aeba 100644 --- a/docs/docs/configuration/connecting-to-data-stores/dynatrace.md +++ b/docs/docs/configuration/connecting-to-data-stores/dynatrace.mdx @@ -1,4 +1,15 @@ -# Dynatrace +--- +id: dynatrace +title: Dynatrace +description: Use Dynatrace as the trace data store for Tracetest. Configure the OpenTelemetry Collector to receive traces and forward them to both Tracetest and Dynatrace. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- If you want to use [Dynatrace](https://www.dynatrace.com/) as the trace data store, you'll configure the OpenTelemetry Collector to receive traces from your system and then send them to both Tracetest and Dynatrace. And, you don't have to change your existing pipelines to do so. @@ -70,7 +81,6 @@ Configure your Tracetest instance to expose an `otlp` endpoint to make it aware In the Web UI, (1) open Settings, and, on the (2) Configure Data Store tab, select (3) Dynatrace. - ![Dynatrace](../img/Dynatrace-settings.png) ## Connect Tracetest to Dynatrace with the CLI @@ -90,10 +100,3 @@ Proceed to run this command in the terminal and specify the file above. ```bash tracetest apply datastore -f my/data-store/file/location.yaml ``` - - diff --git a/docs/docs/configuration/connecting-to-data-stores/elasticapm.md b/docs/docs/configuration/connecting-to-data-stores/elasticapm.mdx similarity index 79% rename from docs/docs/configuration/connecting-to-data-stores/elasticapm.md rename to docs/docs/configuration/connecting-to-data-stores/elasticapm.mdx index 36793023ef..f5f70bd163 100644 --- a/docs/docs/configuration/connecting-to-data-stores/elasticapm.md +++ b/docs/docs/configuration/connecting-to-data-stores/elasticapm.mdx @@ -1,4 +1,15 @@ -# Elastic APM +--- +id: elasticapm +title: Elastic APM +description: Use Elasticsearch as the trace data store for Tracetest. You can use the native connection from Tracetest to pull telemetry data directly from Elasticsearch. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Tracetest fetches traces from [Elasticsearch's default port](https://discuss.elastic.co/t/what-are-ports-9200-and-9300-used-for/238578) `9200`. @@ -28,7 +39,7 @@ To configure Elastic APM you will need to download the CA certificate from the D - Alternatively, you can skip CA certificate validation by setting the `Enable TLS but don't verify the certificate` option. :::tip -Need help configuring the OpenTelemetry Collector so send trace data from your application to Elastic? Read more in [the reference page here](../opentelemetry-collector-configuration-file-reference). +Need help configuring the OpenTelemetry Collector so send trace data from your application to Elastic? Read more in [the reference page here](/configuration/opentelemetry-collector-configuration-file-reference). ::: ## Connect Tracetest to Elastic with the Web UI @@ -41,8 +52,6 @@ https://es01:9200 ![ElasticAPM](../img/ElasticAPM-settings.png) - - ## Connect Tracetest to Elastic with the CLI Or, if you prefer using the CLI, you can use this file config. @@ -69,5 +78,5 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe on running a sample app with Elastic APM and Tracetest](../../examples-tutorials/recipes/running-tracetest-with-elasticapm.md). +To learn more, [read the recipe on running a sample app with Elastic APM and Tracetest](/examples-tutorials/recipes/running-tracetest-with-elasticapm). ::: diff --git a/docs/docs/configuration/connecting-to-data-stores/honeycomb.md b/docs/docs/configuration/connecting-to-data-stores/honeycomb.mdx similarity index 85% rename from docs/docs/configuration/connecting-to-data-stores/honeycomb.md rename to docs/docs/configuration/connecting-to-data-stores/honeycomb.mdx index 4d5fdb1978..c40ce059df 100644 --- a/docs/docs/configuration/connecting-to-data-stores/honeycomb.md +++ b/docs/docs/configuration/connecting-to-data-stores/honeycomb.mdx @@ -1,4 +1,15 @@ -# Honeycomb +--- +id: honeycomb +title: Honeycomb +description: Use Honeycomb as the trace data store for Tracetest. Configure the OpenTelemetry Collector to receive traces and forward them to both Tracetest and Honeycomb. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- If you want to use [Honeycomb](https://honeycomb.io/) as the trace data store, you'll configure the OpenTelemetry Collector to receive traces from your system and then send them to both Tracetest and Honeycomb. And, you don't have to change your existing pipelines to do so. @@ -93,5 +104,5 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe on running a sample app with Honeycomb and Tracetest](../../examples-tutorials/recipes/running-tracetest-with-honeycomb.md). +To learn more, [read the recipe on running a sample app with Honeycomb and Tracetest](/examples-tutorials/recipes/running-tracetest-with-honeycomb). ::: diff --git a/docs/docs/configuration/connecting-to-data-stores/jaeger.md b/docs/docs/configuration/connecting-to-data-stores/jaeger.mdx similarity index 74% rename from docs/docs/configuration/connecting-to-data-stores/jaeger.md rename to docs/docs/configuration/connecting-to-data-stores/jaeger.mdx index fa98798f10..0d657a8627 100644 --- a/docs/docs/configuration/connecting-to-data-stores/jaeger.md +++ b/docs/docs/configuration/connecting-to-data-stores/jaeger.mdx @@ -1,4 +1,15 @@ -# Jaeger +--- +id: jaeger +title: Jaeger +description: Use Jaeger as the trace data store for Tracetest. You can use the native connection from Tracetest to pull telemetry data directly from Jaeger. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Tracetest fetches traces from [Jaeger's gRPC Protobuf/gRPC QueryService](https://www.jaegertracing.io/docs/1.42/deployment/#query-service--ui) on port `16685`. @@ -13,7 +24,7 @@ Configure Tracetest to be aware that it has to fetch trace data from Jaeger. Tracetest uses [Jaeger's gRPC Protobuf/gRPC QueryService](https://www.jaegertracing.io/docs/1.42/deployment/#query-service--ui) on port `16685` to fetch trace data. :::tip -Need help configuring the OpenTelemetry Collector so send trace data from your application to Jaeger? Read more in [the reference page here](../opentelemetry-collector-configuration-file-reference)). +Need help configuring the OpenTelemetry Collector so send trace data from your application to Jaeger? Read more in [the reference page here](/configuration/opentelemetry-collector-configuration-file-reference). ::: ## Connect Tracetest to Jaeger with the Web UI @@ -26,8 +37,6 @@ jaeger:16685 ![Jaeger](../img/Jaeger-settings.png) - - ## Connect Tracetest to Jaeger with the CLI Or, if you prefer using the CLI, you can use this file config. @@ -51,5 +60,5 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe on running a sample app with Jaeger and Tracetest](../../examples-tutorials/recipes/running-tracetest-with-jaeger.md). +To learn more, [read the recipe on running a sample app with Jaeger and Tracetest](/examples-tutorials/recipes/running-tracetest-with-jaeger). ::: diff --git a/docs/docs/configuration/connecting-to-data-stores/lightstep.md b/docs/docs/configuration/connecting-to-data-stores/lightstep.mdx similarity index 86% rename from docs/docs/configuration/connecting-to-data-stores/lightstep.md rename to docs/docs/configuration/connecting-to-data-stores/lightstep.mdx index e44fc471e4..d0de36549b 100644 --- a/docs/docs/configuration/connecting-to-data-stores/lightstep.md +++ b/docs/docs/configuration/connecting-to-data-stores/lightstep.mdx @@ -1,4 +1,15 @@ -# Lightstep +--- +id: lightstep +title: Lightstep +description: Use Lightstep as the trace data store for Tracetest. Configure the OpenTelemetry Collector to receive traces and forward them to both Tracetest and Lightstep. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- If you want to use [Lightstep](https://lightstep.com/) as the trace data store, you'll configure the OpenTelemetry Collector to receive traces from your system and then send them to both Tracetest and Lightstep. And, you don't have to change your existing pipelines to do so. @@ -77,8 +88,6 @@ In the Web UI, (1) open Settings, and, on the (2) Configure Data Store tab, sele ![Lightstep](../img/Lightstep-settings.png) - - ## Connect Tracetest to Lightstep with the CLI Or, if you prefer using the CLI, you can use this file config. @@ -98,5 +107,5 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe on running a sample app with Lightstep and Tracetest](../../examples-tutorials/recipes/running-tracetest-with-lightstep.md). +To learn more, [read the recipe on running a sample app with Lightstep and Tracetest](/examples-tutorials/recipes/running-tracetest-with-lightstep). ::: diff --git a/docs/docs/configuration/connecting-to-data-stores/new-relic.md b/docs/docs/configuration/connecting-to-data-stores/new-relic.mdx similarity index 87% rename from docs/docs/configuration/connecting-to-data-stores/new-relic.md rename to docs/docs/configuration/connecting-to-data-stores/new-relic.mdx index 64030d4b1a..7dc5e79b12 100644 --- a/docs/docs/configuration/connecting-to-data-stores/new-relic.md +++ b/docs/docs/configuration/connecting-to-data-stores/new-relic.mdx @@ -1,4 +1,15 @@ -# New Relic +--- +id: new-relic +title: New Relic +description: Use New Relic as the trace data store for Tracetest. Configure the OpenTelemetry Collector to receive traces and forward them to both Tracetest and New Relic. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- If you want to use [New Relic](https://newrelic.com/) as the trace data store, you'll configure the OpenTelemetry Collector to receive traces from your system and then send them to both Tracetest and New Relic. And, you don't have to change your existing pipelines to do so. @@ -79,8 +90,6 @@ In the Web UI, (1) open Settings, and, on the (2) Configure Data Store tab, sele ![NewRelic](../img/New-Relic-settings.png) - - ## Connect Tracetest to New Relic with the CLI Or, if you prefer using the CLI, you can use this file config. @@ -100,5 +109,5 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe on running a sample app with New Relic and Tracetest](../../examples-tutorials/recipes/running-tracetest-with-new-relic.md). +To learn more, [read the recipe on running a sample app with New Relic and Tracetest](/examples-tutorials/recipes/running-tracetest-with-new-relic). ::: diff --git a/docs/docs/configuration/connecting-to-data-stores/opensearch.md b/docs/docs/configuration/connecting-to-data-stores/opensearch.mdx similarity index 75% rename from docs/docs/configuration/connecting-to-data-stores/opensearch.md rename to docs/docs/configuration/connecting-to-data-stores/opensearch.mdx index 285f252d7d..1986cffa41 100644 --- a/docs/docs/configuration/connecting-to-data-stores/opensearch.md +++ b/docs/docs/configuration/connecting-to-data-stores/opensearch.mdx @@ -1,4 +1,15 @@ -# OpenSearch +--- +id: opensearch +title: OpenSearch +description: Use OpenSearch as the trace data store for Tracetest. You can use the native connection from Tracetest to pull telemetry data directly from OpenSearch. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Tracetest fetches traces from [OpenSearch's default port](https://logz.io/blog/opensearch-tutorial-installation-configuration/#:~:text=This%20is%20because%20OpenSearch%20runs,use%20port%205601%20by%20default.) `9200`. @@ -20,7 +31,7 @@ The defaults can be: - **Address**: `http://opensearch:9200` :::tip -Need help configuring the OpenTelemetry Collector so send trace data from your application to OpenSearch? Read more in [the reference page here](../opentelemetry-collector-configuration-file-reference)). +Need help configuring the OpenTelemetry Collector so send trace data from your application to OpenSearch? Read more in [the reference page here](/configuration/opentelemetry-collector-configuration-file-reference). ::: ## Connect Tracetest to OpenSearch with the Web UI @@ -33,8 +44,6 @@ http://opensearch:9200 ![OpenSearch](../img/opensearch-settings.png) - - ## Connect Tracetest to OpenSearch with the CLI Or, if you prefer using the CLI, you can use this file config. @@ -58,5 +67,5 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe on running a sample app with OpenSearch and Tracetest](../../examples-tutorials/recipes/running-tracetest-with-opensearch.md). +To learn more, [read the recipe on running a sample app with OpenSearch and Tracetest](/examples-tutorials/recipes/running-tracetest-with-opensearch). ::: diff --git a/docs/docs/configuration/connecting-to-data-stores/opentelemetry-collector.md b/docs/docs/configuration/connecting-to-data-stores/opentelemetry-collector.mdx similarity index 84% rename from docs/docs/configuration/connecting-to-data-stores/opentelemetry-collector.md rename to docs/docs/configuration/connecting-to-data-stores/opentelemetry-collector.mdx index c4e350e0d1..35c4ce19e8 100644 --- a/docs/docs/configuration/connecting-to-data-stores/opentelemetry-collector.md +++ b/docs/docs/configuration/connecting-to-data-stores/opentelemetry-collector.mdx @@ -1,4 +1,15 @@ -# OpenTelemetry Collector +--- +id: opentelemetry-collector +title: OpenTelemetry Collector +description: Configure the OpenTelemetry Collector to receive traces and forward them to Tracetest. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Tracetest receives trace data on port `4317`. Tracetest's trace receiver endpoint might look like: @@ -66,7 +77,6 @@ In the Web UI, (1) open Settings, and, on the (2) Configure Data Store tab, sele ![OpenTelemetry](../img/open-telemetry-settings.png) - ## Connect Tracetest to OpenTelemetry Collector with the CLI @@ -87,5 +97,5 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe on running a sample app with OpenTelemetry Collector and Tracetest](../../examples-tutorials/recipes/running-tracetest-without-a-trace-data-store.mdx). +To learn more, [read the recipe on running a sample app with OpenTelemetry Collector and Tracetest](/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store). ::: diff --git a/docs/docs/configuration/connecting-to-data-stores/signalfx.md b/docs/docs/configuration/connecting-to-data-stores/signalfx.mdx similarity index 72% rename from docs/docs/configuration/connecting-to-data-stores/signalfx.md rename to docs/docs/configuration/connecting-to-data-stores/signalfx.mdx index f6642488eb..a53b0631aa 100644 --- a/docs/docs/configuration/connecting-to-data-stores/signalfx.md +++ b/docs/docs/configuration/connecting-to-data-stores/signalfx.mdx @@ -1,4 +1,15 @@ -# SignalFx +--- +id: signalfx +title: SignalFx +description: Use SignalFx as the trace data store for Tracetest. You can use the native connection from Tracetest to pull telemetry data directly from SignalFx. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Tracetest fetches traces from [SignalFx's realm and token](https://docs.splunk.com/Observability/references/organizations.html). @@ -11,7 +22,7 @@ Examples of configuring Tracetest can be found in the [`examples` folder of the Configure Tracetest to be aware that it has to fetch trace data from SignalFx. :::tip -Need help configuring the OpenTelemetry Collector so send trace data from your application to SignalFx? Read more in [the reference page here](../opentelemetry-collector-configuration-file-reference)). +Need help configuring the OpenTelemetry Collector so send trace data from your application to SignalFx? Read more in [the reference page here](/configuration/opentelemetry-collector-configuration-file-reference). ::: ## Connect Tracetest to SignalFx with the Web UI @@ -27,7 +38,6 @@ Follow this [guide](https://docs.splunk.com/Observability/references/organizatio ![SignalFX](../img/SignalFX-settings.png) - ## Connect Tracetest to SignalFx with the CLI diff --git a/docs/docs/configuration/connecting-to-data-stores/signoz.md b/docs/docs/configuration/connecting-to-data-stores/signoz.mdx similarity index 68% rename from docs/docs/configuration/connecting-to-data-stores/signoz.md rename to docs/docs/configuration/connecting-to-data-stores/signoz.mdx index 02f660083f..1708fb53a8 100644 --- a/docs/docs/configuration/connecting-to-data-stores/signoz.md +++ b/docs/docs/configuration/connecting-to-data-stores/signoz.mdx @@ -1,12 +1,23 @@ -# Signoz - -If you want to use [Signoz](https://signoz.io/) as the trace data store, you'll configure the OpenTelemetry Collector to receive traces from your system and then send them to both Tracetest and Signoz. And, you don't have to change your existing pipelines to do so. +--- +id: signoz +title: SigNoz +description: Use SigNoz as the trace data store for Tracetest. Configure the OpenTelemetry Collector to receive traces and forward them to both Tracetest and SigNoz. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- + +If you want to use [SigNoz](https://signoz.io/) as the trace data store, you'll configure the OpenTelemetry Collector to receive traces from your system and then send them to both Tracetest and Signoz. And, you don't have to change your existing pipelines to do so. :::tip -Examples of configuring Tracetest with Signoz can be found in the [`examples` folder of the Tracetest GitHub repo](https://github.com/kubeshop/tracetest/tree/main/examples). +Examples of configuring Tracetest with SigNoz can be found in the [`examples` folder of the Tracetest GitHub repo](https://github.com/kubeshop/tracetest/tree/main/examples). ::: -## Configuring OpenTelemetry Collector to Send Traces to both Signoz and Tracetest +## Configuring OpenTelemetry Collector to Send Traces to both SigNoz and Tracetest In your OpenTelemetry Collector config file: @@ -20,7 +31,7 @@ If you are running Tracetest with Docker, and Tracetest's service name is `trace Additionally, add another config: - Set the `exporter` to `otlp/signoz` -- Set the `endpoint` to your Signoz instance on port `4317` +- Set the `endpoint` to your SigNoz instance on port `4317` ```yaml # collector.config.yaml @@ -45,9 +56,9 @@ exporters: endpoint: tracetest:4317 # Send traces to Tracetest. Read more in docs here: https://docs.tracetest.io/configuration/connecting-to-data-stores/opentelemetry-collector tls: insecure: true - # OTLP for Signoz + # OTLP for SigNoz otlp/signoz: - endpoint: address-to-your-signoz-server:4317 # Send traces to Signoz. Read more in docs here: https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/#opentelemetry-collector-configuration + endpoint: address-to-your-signoz-server:4317 # Send traces to SigNoz. Read more in docs here: https://signoz.io/docs/tutorial/opentelemetry-binary-usage-in-virtual-machine/#opentelemetry-collector-configuration tls: insecure: true service: @@ -56,31 +67,30 @@ service: receivers: [otlp] processors: [batch] exporters: [logging, otlp/tracetest] - traces/signoz: # Pipeline to send data to Signoz + traces/signoz: # Pipeline to send data to SigNoz receivers: [otlp] processors: [batch] exporters: [logging, otlp/signoz] ``` -## Configure Tracetest to Use Signoz as a Trace Data Store +## Configure Tracetest to Use SigNoz as a Trace Data Store Configure your Tracetest instance to expose an `otlp` endpoint to make it aware it will receive traces from the OpenTelemetry Collector. This will expose Tracetest's trace receiver on port `4317`. -## Connect Tracetest to Signoz with the Web UI +## Connect Tracetest to SigNoz with the Web UI -In the Web UI, (1) open Settings, and, on the (2) Configure Data Store tab, select (3) Signoz. +In the Web UI, (1) open Settings, and, on the (2) Configure Data Store tab, select (3) SigNoz. - -![Signoz](../img/Signoz-settings.png) +![SigNoz](../img/Signoz-settings.png) -## Connect Tracetest to Signoz with the CLI +## Connect Tracetest to SigNoz with the CLI Or, if you prefer using the CLI, you can use this file config. ```yaml type: DataStore spec: - name: Signoz pipeline + name: SigNoz pipeline type: signoz default: true ``` @@ -92,5 +102,5 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe on running a sample app with Signoz and Tracetest](../../examples-tutorials/recipes/running-tracetest-with-signoz-pokeshop.md). +To learn more, [read the recipe on running a sample app with SigNoz and Tracetest](/examples-tutorials/recipes/running-tracetest-with-signoz-pokeshop). ::: diff --git a/docs/docs/configuration/connecting-to-data-stores/tempo.md b/docs/docs/configuration/connecting-to-data-stores/tempo.mdx similarity index 87% rename from docs/docs/configuration/connecting-to-data-stores/tempo.md rename to docs/docs/configuration/connecting-to-data-stores/tempo.mdx index e33edbecd1..b9ca666bef 100644 --- a/docs/docs/configuration/connecting-to-data-stores/tempo.md +++ b/docs/docs/configuration/connecting-to-data-stores/tempo.mdx @@ -1,4 +1,15 @@ -# Tempo +--- +id: tempo +title: Grafana Tempo +description: Use Grafana Tempo as the trace data store for Tracetest. You can use the native connection from Tracetest to pull telemetry data directly from Tempo. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Tracetest fetches traces from [Tempo on the default gRPC port](https://grafana.com/docs/tempo/latest/configuration/#server) `9095`, or [default HTTP port](https://grafana.com/docs/tempo/latest/configuration/#server) `80`. @@ -63,7 +74,7 @@ Configure Tracetest to be aware that it has to fetch trace data from Tempo. Tracetest uses [Tempo's gRPC endpoint](https://grafana.com/docs/tempo/latest/configuration/#server) on port `9095` to fetch trace data. Alternatively, you can use Tempo's HTTP endpoint and default port `80`. :::tip -Need help configuring the OpenTelemetry Collector so send trace data from your application to Jaeger? Read more in [the reference page here](../opentelemetry-collector-configuration-file-reference)). +Need help configuring the OpenTelemetry Collector so send trace data from your application to Jaeger? Read more in [the reference page here](/configuration/opentelemetry-collector-configuration-file-reference). ::: ## Connect Tracetest to Tempo with the Web UI @@ -78,8 +89,6 @@ tempo:9095 ![Tempo](../img/Tempo-settings.png) - - If you are using Docker and the `HTTP` URL like in the screenshot below, use the service name as the hostname with port `80` or no specified port like this: ``` @@ -88,8 +97,6 @@ http://tempo ![Tempo](../img/Tempo-settings.png) - - ## Connect Tracetest to Tempo with the CLI Or, if you prefer using the CLI, you can use this file config. @@ -133,5 +140,5 @@ tracetest apply datastore -f my/data-store/file/location.yaml ``` :::tip -To learn more, [read the recipe on running a sample app with Tempo and Tracetest](../../examples-tutorials/recipes/running-tracetest-with-tempo.md). +To learn more, [read the recipe on running a sample app with Tempo and Tracetest](/examples-tutorials/recipes/running-tracetest-with-tempo). ::: diff --git a/docs/docs/configuration/demo.md b/docs/docs/configuration/demo.mdx similarity index 81% rename from docs/docs/configuration/demo.md rename to docs/docs/configuration/demo.mdx index 489d589c0a..46ac4237ec 100644 --- a/docs/docs/configuration/demo.md +++ b/docs/docs/configuration/demo.mdx @@ -1,4 +1,15 @@ -# Demo Settings +--- +id: demo +title: Demo Settings +description: Enable test examples for the Pokeshop Demo App or the OpenTelemetry Astronomy Shop Demo in Tracetest. Edit the demo settings in the Web UI and CLI. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Tracetest has the option to enable Test examples for our Pokeshop Demo App or the OpenTelemetry Astronomy Shop Demo. You will need an instance of those applications running alongside your Tracetest server to be able to use them. The demo settings can be adjusted both from the Tracetest UI and from the CLI. diff --git a/docs/docs/configuration/opentelemetry-collector-configuration-file-reference.md b/docs/docs/configuration/opentelemetry-collector-configuration-file-reference.mdx similarity index 85% rename from docs/docs/configuration/opentelemetry-collector-configuration-file-reference.md rename to docs/docs/configuration/opentelemetry-collector-configuration-file-reference.mdx index da3e849558..ac3948e7b0 100644 --- a/docs/docs/configuration/opentelemetry-collector-configuration-file-reference.md +++ b/docs/docs/configuration/opentelemetry-collector-configuration-file-reference.mdx @@ -1,4 +1,15 @@ -# OpenTelemetry Collector Configuration File Reference +--- +id: opentelemetry-collector-configuration-file-reference +title: OpenTelemetry Collector Configuration File Reference +description: This is a reference for using the OpenTelemetry Collector to send trace data from your application to any of Tracetest's supported trace data stores. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- This page contains a reference for using the OpenTelemetry Collector to send trace data from your application to any of Tracetest's supported trace data stores. @@ -12,18 +23,19 @@ Tracetest is designed to work with different trace data stores. To enable Tracet Currently, Tracetest supports the following data stores. Click on the respective data store to view configuration examples: -- [Jaeger](./connecting-to-data-stores/jaeger) -- [OpenSearch](./connecting-to-data-stores/opensearch) -- [Elastic APM](./connecting-to-data-stores/elasticapm) -- [SignalFX](./connecting-to-data-stores/signalfx) -- [Grafana Tempo](./connecting-to-data-stores/tempo) -- [Lightstep](./connecting-to-data-stores/lightstep) -- [New Relic](./connecting-to-data-stores/new-relic) -- [AWS X-Ray](./connecting-to-data-stores/awsxray.md) -- [Datadog](./connecting-to-data-stores/datadog) -- [Honeycomb](./connecting-to-data-stores/honeycomb.md) -- [Azure App Insights](./connecting-to-data-stores/azure-app-insights.md) -- [Dynatrace](./connecting-to-data-stores/dynatrace) +- [AWS X-Ray](/configuration/connecting-to-data-stores/awsxray) +- [Azure App Insights](/configuration/connecting-to-data-stores/azure-app-insights) +- [Datadog](/configuration/connecting-to-data-stores/datadog) +- [Dynatrace](/configuration/connecting-to-data-stores/dynatrace) +- [Elastic APM](/configuration/connecting-to-data-stores/elasticapm) +- [Grafana Tempo](/configuration/connecting-to-data-stores/tempo) +- [Honeycomb](/configuration/connecting-to-data-stores/honeycomb) +- [Jaeger](/configuration/connecting-to-data-stores/jaeger) +- [Lightstep](/configuration/connecting-to-data-stores/lightstep) +- [New Relic](/configuration/connecting-to-data-stores/new-relic) +- [OpenSearch](/configuration/connecting-to-data-stores/opensearch) +- [SignalFX](/configuration/connecting-to-data-stores/signalfx) +- [SigNoz](/configuration/connecting-to-data-stores/signoz) Continue reading below to learn how to configure the OpenTelemetry Collector to send trace data from your application to any of the trace data stores above. diff --git a/docs/docs/configuration/overview.mdx b/docs/docs/configuration/overview.mdx index 26256790b3..f78b59acd4 100644 --- a/docs/docs/configuration/overview.mdx +++ b/docs/docs/configuration/overview.mdx @@ -8,12 +8,12 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- There is one configuration option with Tracetest: -- [Agent configuration](./agent.mdx) to run it locally, in Docker, or Kubernetes. +- [Agent configuration](/configuration/agent) to run it locally, in Docker, or Kubernetes. ## Supported Trace Data Stores @@ -21,26 +21,26 @@ Tracetest is designed to work with different trace data stores. To enable Tracet Currently, Tracetest supports the following data stores. Click on the respective data store to view configuration examples: -- [AWS X-Ray](./connecting-to-data-stores/awsxray) -- [Azure App Insights](./connecting-to-data-stores/azure-app-insights.md) -- [Datadog](./connecting-to-data-stores/datadog) -- [Dynatrace](./connecting-to-data-stores/dynatrace) -- [Elastic APM](./connecting-to-data-stores/elasticapm) -- [Grafana Tempo](./connecting-to-data-stores/tempo) -- [Honeycomb](./connecting-to-data-stores/honeycomb) -- [Jaeger](./connecting-to-data-stores/jaeger) -- [Lightstep](./connecting-to-data-stores/lightstep) -- [New Relic](./connecting-to-data-stores/new-relic) -- [OpenSearch](./connecting-to-data-stores/opensearch) -- [OpenTelemetry Collector](./connecting-to-data-stores/opentelemetry-collector) -- [SignalFX](./connecting-to-data-stores/signalfx) -- [Signoz](./connecting-to-data-stores/signoz) +- [AWS X-Ray](/configuration/connecting-to-data-stores/awsxray) +- [Azure App Insights](/configuration/connecting-to-data-stores/azure-app-insights) +- [Datadog](/configuration/connecting-to-data-stores/datadog) +- [Dynatrace](/configuration/connecting-to-data-stores/dynatrace) +- [Elastic APM](/configuration/connecting-to-data-stores/elasticapm) +- [Grafana Tempo](/configuration/connecting-to-data-stores/tempo) +- [Honeycomb](/configuration/connecting-to-data-stores/honeycomb) +- [Jaeger](/configuration/connecting-to-data-stores/jaeger) +- [Lightstep](/configuration/connecting-to-data-stores/lightstep) +- [New Relic](/configuration/connecting-to-data-stores/new-relic) +- [OpenSearch](/configuration/connecting-to-data-stores/opensearch) +- [OpenTelemetry Collector](/configuration/connecting-to-data-stores/opentelemetry-collector) +- [SignalFX](/configuration/connecting-to-data-stores/signalfx) +- [Signoz](/configuration/connecting-to-data-stores/signoz) ## Using Tracetest without a Trace Data Store Another option is to send traces directly to Tracetest using the OpenTelemetry Collector. And, you don't have to change your existing pipelines to do so. -View [configuration for OpenTelemetry Collector](./connecting-to-data-stores/opentelemetry-collector.md) for more details. +View [configuration for OpenTelemetry Collector](/configuration/connecting-to-data-stores/opentelemetry-collector) for more details. ## Trace Data Store Configuration Examples diff --git a/docs/docs/configuration/sampling-tracetest-spans.md b/docs/docs/configuration/sampling-tracetest-spans.mdx similarity index 87% rename from docs/docs/configuration/sampling-tracetest-spans.md rename to docs/docs/configuration/sampling-tracetest-spans.mdx index 110ceb834b..7eedfd7b0b 100644 --- a/docs/docs/configuration/sampling-tracetest-spans.md +++ b/docs/docs/configuration/sampling-tracetest-spans.mdx @@ -1,4 +1,15 @@ -# Sampling Tracetest Spans +--- +id: sampling-tracetest-spans +title: Sampling Tracetest Spans +description: When running Tracetest in production, your test spans could not be sampled by your probabilistic sampler. Here's how to avoid sampling out Tracetest test spans. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Suppose you are considering Tracetest to run tests against a high-volume environment, such as production. In that case, you probably will hit some drawbacks, such as having your test spans not sampled by your probabilistic sampler. There are a couple of things that you can do to avoid those problems: diff --git a/docs/docs/configuration/test-runner.md b/docs/docs/configuration/test-runner.mdx similarity index 58% rename from docs/docs/configuration/test-runner.md rename to docs/docs/configuration/test-runner.mdx index df2c1c41a6..954aacc80a 100644 --- a/docs/docs/configuration/test-runner.md +++ b/docs/docs/configuration/test-runner.mdx @@ -1,4 +1,15 @@ -# Test Runner Settings +--- +id: test-runner +title: Test Runner Settings +description: The Test Runner settings configure the default behavior used when executing tests to determine whether to mark the test as passed or failed. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- The Test Runner settings allow you to configure the default behavior used when executing your tests to determine whether to mark the test as passed or failed. Only the enabled gates will be will be used to determine whether a test is passed or failed. @@ -8,7 +19,6 @@ In the Tracetest settings, on the **Test Runner** tab, select the default gates ![Test Runner](./img/test-runner-settings.png) -For a specific test, change the gates used when running that test from the **Automate** tab: +For a specific test, change the gates used when running that test from the **Automate** tab: ![Test Runner Settings in App](./img/test-runner-in-app.png) - diff --git a/docs/docs/configuration/trace-polling.md b/docs/docs/configuration/trace-polling.mdx similarity index 85% rename from docs/docs/configuration/trace-polling.md rename to docs/docs/configuration/trace-polling.mdx index 8a771d2291..b0e287c1a4 100644 --- a/docs/docs/configuration/trace-polling.md +++ b/docs/docs/configuration/trace-polling.mdx @@ -1,4 +1,15 @@ -# Trace Polling Settings +--- +id: trace-polling +title: Trace Polling Settings +description: Tracetest polls the trace data store to find and retrieve the trace that is generated by the current test run. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Tracetest currently has one algorithm for gathering the trace associated with a test which is based on periodic polling. We will be adding the ability to add multiple polling settings in the coming releases, as well as adding new polling strategies. Let us know as you have specific needs by [adding an issue](https://github.com/kubeshop/tracetest/issues/new/choose). diff --git a/docs/docs/configuration/tracetest-analyzer.md b/docs/docs/configuration/tracetest-analyzer.mdx similarity index 74% rename from docs/docs/configuration/tracetest-analyzer.md rename to docs/docs/configuration/tracetest-analyzer.mdx index d4fef720f8..a18f273d3b 100644 --- a/docs/docs/configuration/tracetest-analyzer.md +++ b/docs/docs/configuration/tracetest-analyzer.mdx @@ -1,9 +1,20 @@ -# Tracetest Analyzer Settings +--- +id: tracetest-analyzer +title: Tracetest Analyzer Settings +description: Tracetest Analyzer is provided in the Tracetest application to aid in the analysis of traces and easily pinpoint issues to speed up resolution. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- Tracetest Analyzer is provided in the Tracetest application to aid in the analysis of traces and easily pinpoint issues to speed up resolution. :::tip -[Read more about Tracetest Analyzer concepts here.](../analyzer/concepts.md) +[Read more about Tracetest Analyzer concepts here.](/analyzer/concepts) ::: ## Create a Test @@ -52,4 +63,4 @@ Here, you can also set the thresholds for `Otel Semantic Conventions`, `Common P ## Tracetest Analyzer in the CLI -You can use Tracetest Analyzer in the CLI to analyze per individual test. Visit the [Creating Transactions](../web-ui/creating-test-suites.md) page for details. +You can use Tracetest Analyzer in the CLI to analyze per individual test. Visit the [Creating Transactions](/web-ui/creating-test-suites) page for details. diff --git a/docs/docs/core/configuration/analytics.mdx b/docs/docs/core/configuration/analytics.mdx index 35d3106f59..19fab364d1 100644 --- a/docs/docs/core/configuration/analytics.mdx +++ b/docs/docs/core/configuration/analytics.mdx @@ -1,14 +1,14 @@ --- id: analytics title: Analytics Settings -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. Learn how to get started with creating tests once you open Tracetest. +description: To improve the end user experience and to help determine where to focus team resources to improve the tool, Tracetest collects analytics and telemetry information. keywords: - tracetest - trace-based testing - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- To improve the end user experience and to help determine where to focus team resources to improve the tool, Tracetest collects analytics and telemetry information from the system. diff --git a/docs/docs/core/configuration/overview.mdx b/docs/docs/core/configuration/overview.mdx index c519868f4e..c22d381b50 100644 --- a/docs/docs/core/configuration/overview.mdx +++ b/docs/docs/core/configuration/overview.mdx @@ -1,39 +1,39 @@ --- id: overview title: Configuration -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. Learn how to get started with creating tests once you open Tracetest. +description: Tracetest Core configuration options include both Server and Provisioning on startup. This includes trace data stores as well. keywords: - tracetest - trace-based testing - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- There are several configuration options with Tracetest Core: -- [Server configuration](./server) to set database connection information needed to connect to required PostgreSQL instance. -- [Provisioning configuration](./provisioning) to 'preload' the Tracetest server with resources when first running the Tracetest server. +- [Server configuration](/core/configuration/server) to set database connection information needed to connect to required PostgreSQL instance. +- [Provisioning configuration](/core/configuration/provisioning) to 'preload' the Tracetest server with resources when first running the Tracetest server. ## Supported Trace Data Stores Tracetest is designed to work with different trace data stores. To enable Tracetest to run end-to-end tests against trace data, you need to configure Tracetest to access trace data. -Currently, Tracetest supports the [following data stores](../../configuration/overview). +Currently, Tracetest supports the [following data stores](/configuration/overview). ## Configuring Tracetest Server -Tracetest has a configuration file to contain the minimal information needed to start the Tracetest server. See more at [Tracetest Server Configuration](./server). +Tracetest has a configuration file to contain the minimal information needed to start the Tracetest server. See more at [Tracetest Server Configuration](/core/configuration/server). -You can also provision the server when it first starts, configuring most aspects of your Tracetest server environment. This is useful in a CI/CD environment to preload and configure the server. See more at [Provisioning a Tracetest Server](./provisioning). +You can also provision the server when it first starts, configuring most aspects of your Tracetest server environment. This is useful in a CI/CD environment to preload and configure the server. See more at [Provisioning a Tracetest Server](/core/configuration/provisioning). Many of the server configuration settings can be set individually in the UI or via the CLI. See: -- [Trace Polling](../../configuration/trace-polling.md) -- [Test Runner](../../configuration/test-runner.md) -- [Demo Applications](../../configuration/demo.md) -- [Analytics](./analytics.mdx) -- [Telemetry](./telemetry.mdx) +- [Trace Polling](/configuration/trace-polling) +- [Test Runner](/configuration/test-runner) +- [Demo Applications](/configuration/demo) +- [Analytics](/core/configuration/analytics) +- [Telemetry](/core/configuration/telemetry) diff --git a/docs/docs/core/configuration/provisioning.mdx b/docs/docs/core/configuration/provisioning.mdx index 2f21ea4694..372680600e 100644 --- a/docs/docs/core/configuration/provisioning.mdx +++ b/docs/docs/core/configuration/provisioning.mdx @@ -1,14 +1,14 @@ --- id: provisioning title: Provisioning a Tracetest Server -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. Learn how to get started with creating tests once you open Tracetest. +description: Tracetest Core enables the Tracetest Server to be provisioned the first time a new Tracetest Server is installed and launched. keywords: - tracetest - trace-based testing - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- Tracetest allows a server to be provisioned the first time a new Tracetest server is installed and launched. Provisioning sets certain resources in the server to the specified values, allowing you to configure the server. It is convenient in a CI/CD flow where you want to launch a server with a specified configuration. diff --git a/docs/docs/core/configuration/server.mdx b/docs/docs/core/configuration/server.mdx index 65f3b63e01..30a1dde502 100644 --- a/docs/docs/core/configuration/server.mdx +++ b/docs/docs/core/configuration/server.mdx @@ -1,14 +1,14 @@ --- id: server title: Configuring the Tracetest Server -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. Learn how to get started with creating tests once you open Tracetest. +description: Tracetest Core requires a minimal configuration to be launched. Connect to a PostgreSQL database which is installed as part of the "tracetest server install" command. keywords: - tracetest - trace-based testing - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- Tracetest requires a very minimal configuration to be launched, needing just the connection information to connect with the PostgreSQL database which is installed as part of the server install. There are a couple of ways to provide this database connection information. @@ -60,4 +60,4 @@ You can also change the defaults for the Tracetest server, altering the port and - `TRACETEST_SERVER_HTTPPORT=11633` - `TRACETEST_SERVER_PATHPREFIX="/"` -You can also initialize the server with a number of resources the first time it is launched by using [provisioning](./provisioning). +You can also initialize the server with a number of resources the first time it is launched by using [provisioning](/core/configuration/provisioning). diff --git a/docs/docs/core/configuration/telemetry.mdx b/docs/docs/core/configuration/telemetry.mdx index 83f5dd38aa..2c298842d6 100644 --- a/docs/docs/core/configuration/telemetry.mdx +++ b/docs/docs/core/configuration/telemetry.mdx @@ -1,14 +1,14 @@ --- id: telemetry title: Telemetry -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. Learn how to get started with creating tests once you open Tracetest. +description: The Tracetest Core Server generates internal observability trace data. You can use this data to track test runs over time and gain observability of how the Tracetest Core Server is behaving. keywords: - tracetest - trace-based testing - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- The Tracetest server generates internal observability trace data. You can use this data to track Tracetest test runs over time and gain observability of how the Tracetest server is behaving. @@ -17,9 +17,9 @@ The Tracetest team uses an observability-driven development approach in developi ## Configuring Tracetest Server Internal Telemetry -You can configure an exporter to send the trace data to an OpenTelemetry Collector and then store it safely in your trace data store for further historical analysis. View the [supported trace data stores](./overview#supported-trace-data-stores) for more guidance on setting them up. +You can configure an exporter to send the trace data to an OpenTelemetry Collector and then store it safely in your trace data store for further historical analysis. View the [supported trace data stores](/core/configuration/overview#supported-trace-data-stores) for more guidance on setting them up. -In the `tracetest-config.yaml` file, alongside the [configuration](./server.mdx) of connecting Tracetest to the Postgres instance, you can also define a `telemetry` and `server` section. +In the `tracetest-config.yaml` file, alongside the [configuration](/core/configuration/server) of connecting Tracetest to the Postgres instance, you can also define a `telemetry` and `server` section. With these two additional sections, you define an exporter where the Tracetest server's internal telemetry will be routed to. In the `telemetry` section, you define the endpoint of the OpenTelemetry Collector. And, in the `server` section you define which exporter the Tracetest server will use. diff --git a/docs/docs/core/configuration/upgrade.mdx b/docs/docs/core/configuration/upgrade.mdx index 37beb7856b..e967d28908 100644 --- a/docs/docs/core/configuration/upgrade.mdx +++ b/docs/docs/core/configuration/upgrade.mdx @@ -1,14 +1,14 @@ --- id: upgrade title: Upgrade Tracetest Version -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. Learn how to get started with creating tests once you open Tracetest. +description: This page explains how to upgrade the version of your Tracetest Core Server and CLI if their version are incompatible. keywords: - tracetest - trace-based testing - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- This page explains how to upgrade the version of your Tracetest Server and CLI. diff --git a/docs/docs/core/deployment/docker.md b/docs/docs/core/deployment/docker.mdx similarity index 72% rename from docs/docs/core/deployment/docker.md rename to docs/docs/core/deployment/docker.mdx index 78724e8438..b1037c19ec 100644 --- a/docs/docs/core/deployment/docker.md +++ b/docs/docs/core/deployment/docker.mdx @@ -1,13 +1,23 @@ -# Docker Deployment - -This guide walks you through using the Tracetest CLI to deploy Tracetest with Docker. +--- +id: docker +title: Docker Deployment +description: Guides for deploying Tracetest Core with Docker. Tracetest Core allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- + +This guide walks you through using the Tracetest CLI to deploy Tracetest Core with Docker. :::note This is an example of a production-ready deployment, but real-world deployments can vary significantly depending on desired performance and scale. ::: -In this form, Tracetest runs in parallel to your Dockerized application, -allowing you to interact with your app and its traces, create and run tests over them, etc. +Tracetest Core runs in parallel with your Dockerized application, allowing you to interact with your app and its traces, including create and run tests against them. After installing the CLI, run: diff --git a/docs/docs/core/deployment/kubernetes.mdx b/docs/docs/core/deployment/kubernetes.mdx index d2ab2a6ba1..4ac0b73be6 100644 --- a/docs/docs/core/deployment/kubernetes.mdx +++ b/docs/docs/core/deployment/kubernetes.mdx @@ -1,28 +1,35 @@ -# Kubernetes Deployment - - +--- +id: kubernetes +title: Kubernetes Deployment +description: Guides for deploying Tracetest Core in Kubernetes. Tracetest Core allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; - - -This guide walks you through deploying Tracetest with Kubernetes. +This guide walks you through deploying Tracetest Core in Kubernetes. :::note This is an example of a production-ready deployment, but real-world deployments can vary significantly depending on desired performance and scale. This setup is ideal for CI/CD environments and QA teams working in shared environments. You can use a remote or local ([minikube](https://minikube.sigs.k8s.io/docs/start/), [kind](https://kind.sigs.k8s.io/), [k3d](https://k3d.io/), etc) cluster. ::: -You have two options to install Tracetest on Kubernetes: +You have two options to install Tracetest Core in Kubernetes: -- Using the [Tracetest CLI](../getting-started/installation) to guide your installation +- Using the [Tracetest CLI](/core/getting-started/installation) to guide your installation - Using the official [Helm chart](https://github.com/kubeshop/helm-charts/tree/main/charts/tracetest) -First, install Tracetest CLI following the instructions on [Getting Started](../getting-started/installation#install-the-tracetest-cli). +First, install Tracetest CLI following the instructions on [Getting Started](/core/getting-started/installation#install-the-tracetest-cli). After installing the CLI, run: @@ -36,8 +43,6 @@ How do you want to run TraceTest? [type to search]: > Using Kubernetes ``` - - Select `Using Kubernetes` and follow the instructions. **Tools required (installed if missing)**: diff --git a/docs/docs/core/deployment/overview.md b/docs/docs/core/deployment/overview.mdx similarity index 68% rename from docs/docs/core/deployment/overview.md rename to docs/docs/core/deployment/overview.mdx index a4f5298a0c..e9faf59ab2 100644 --- a/docs/docs/core/deployment/overview.md +++ b/docs/docs/core/deployment/overview.mdx @@ -1,14 +1,23 @@ -# Deployment +--- +id: overview +title: Deployment +description: Guides for deploying Tracetest Core. Tracetest Core allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- This section contains a general overview of deploying Tracetest in production. You can find platform-specific guides for: -- [Docker](./docker) -- [Kubernetes](./kubernetes) +- [Docker](/core/deployment/docker) +- [Kubernetes](/core/deployment/kubernetes) As shown in the diagram below, a typical production Tracetest deployment consists of Postgres, an OpenTelemetry Colletor and a [trace data store](/configuration/overview.mdx). But, if you do not want to use a trace data store, you can rely entirely on OpenTelemetry Collector. - - ```mermaid flowchart TD A(("Tracetest")) @@ -48,4 +57,4 @@ postgres: Read more in the [configuration docs](/configuration/overview.mdx). -Or, continue reading to see how to run Tracetest in production with [Docker](./docker) or [Kubernetes](./kubernetes). +Or, continue reading to see how to run Tracetest Core in production with [Docker](/core/deployment/docker) or [Kubernetes](/core/deployment/kubernetes). diff --git a/docs/docs/core/getting-started/installation.mdx b/docs/docs/core/getting-started/installation.mdx index 8203bc5d55..9c69a837e1 100644 --- a/docs/docs/core/getting-started/installation.mdx +++ b/docs/docs/core/getting-started/installation.mdx @@ -1,14 +1,14 @@ --- id: installation title: Installing Tracetest Core -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. +description: Get started with installing Tracetest Core. Tracetest Core allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. keywords: - tracetest - trace-based testing - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- import Tabs from '@theme/Tabs'; @@ -18,14 +18,14 @@ import GtagInstallCliTabs from '@site/src/components/GtagInstallCliTabs'; This page showcases getting started with Tracetest Core by using the Tracetest CLI, Docker, or Kubernetes. -This simple installation includes a demo app called [Pokeshop](/live-examples/pokeshop/overview.md) that will be installed alongside Tracetest Core. It shows how to configure OpenTelemetry and Tracetest Core and the architecture of the Pokeshop sample app. +This simple installation includes a demo app called [Pokeshop](/live-examples/pokeshop/overview) that will be installed alongside Tracetest Core. It shows how to configure OpenTelemetry and Tracetest Core and the architecture of the Pokeshop sample app. ## Install the Tracetest CLI :::tip Want more info? -Read the CLI installation reference [here](/cli/cli-installation-reference.md). +Read the CLI installation reference [here](/cli/cli-installation-reference). ::: ## Install the Tracetest Server @@ -56,7 +56,7 @@ tracetest server install Using Kubernetes`} -Choose to install Tracetest with the OpenTelemetry Collector and the [Pokeshop](/live-examples/pokeshop/overview.md) sample app. +Choose to install Tracetest with the OpenTelemetry Collector and the [Pokeshop](/live-examples/pokeshop/overview) sample app. ```text title="Expected output:" Do you have OpenTelemetry based tracing already set up, or would you like us to install a demo tracing environment and app? [type to search]: @@ -67,7 +67,7 @@ Do you have OpenTelemetry based tracing already set up, or would you like us to Choosing any option, this installer will create a `tracetest` directory in the current directory and add a `docker-compose.yaml` file to it. - If you choose the first option, the `docker-compose.yaml` will have only Tracetest Core and its dependencies. -- **By choosing the second option, a sample app called [Pokeshop](/live-examples/pokeshop/overview.md) will be installed with Tracetest Core, allowing you to create sample tests right away!** +- **By choosing the second option, a sample app called [Pokeshop](/live-examples/pokeshop/overview) will be installed with Tracetest Core, allowing you to create sample tests right away!**
@@ -129,7 +129,7 @@ This will start the Tracetest Server and expose the Web UI on [`http://localhost > Using Kubernetes`} -Choose to install Tracetest Core with the OpenTelemetry Collector and the [Pokeshop](/live-examples/pokeshop/overview.md) sample app. +Choose to install Tracetest Core with the OpenTelemetry Collector and the [Pokeshop](/live-examples/pokeshop/overview) sample app. ```text title="Expected output:" Do you have OpenTelemetry based tracing already set up, or would you like us to install a demo tracing environment and app? [type to search]: @@ -140,7 +140,7 @@ Do you have OpenTelemetry based tracing already set up, or would you like us to Choosing any option, this installer will create a `tracetest` namespace in the Kubernetes context you choose and create deployments for Tracetest Core and its dependencies. - If you choose the first option, the `tracetest` namespace will only contain Tracetest Core and its dependencies. -- **By choosing the second option, a sample app called [Pokeshop](/live-examples/pokeshop/overview.md) will be installed in a `demo` namespace alongside Tracetest Core, allowing you to create sample tests right away!** +- **By choosing the second option, a sample app called [Pokeshop](/live-examples/pokeshop/overview) will be installed in a `demo` namespace alongside Tracetest Core, allowing you to create sample tests right away!**
@@ -239,7 +239,7 @@ First, be sure that you have [Docker](https://docker.com/) installed in your mac The Quick Start with the Pokeshop Sample App is located [here](https://github.com/kubeshop/tracetest/tree/main/examples/quick-start-pokeshop). -**The [`docker-compose.yaml`](https://github.com/kubeshop/tracetest/blob/main/examples/quick-start-pokeshop/docker-compose.yml) contains Tracetest Core, the OpenTelemetry Collector, and a sample app called [Pokeshop](/live-examples/pokeshop/overview.md). This allows you to create sample tests right away!** +**The [`docker-compose.yaml`](https://github.com/kubeshop/tracetest/blob/main/examples/quick-start-pokeshop/docker-compose.yml) contains Tracetest Core, the OpenTelemetry Collector, and a sample app called [Pokeshop](/live-examples/pokeshop/overview). This allows you to create sample tests right away!**
@@ -294,7 +294,7 @@ This will start the Tracetest Server and expose the Web UI on [`http://localhost :::tip Don't have OpenTelemetry installed? -Tracetest requires that you have [OpenTelemetry instrumentation](https://opentelemetry.io/docs/instrumentation/) added in your code, and configured [sending traces to a trace data store](/configuration/connecting-to-data-stores/jaeger.md), or [Tracetest directly](/configuration/connecting-to-data-stores/opentelemetry-collector.md). +Tracetest requires that you have [OpenTelemetry instrumentation](https://opentelemetry.io/docs/instrumentation/) added in your code, and configured [sending traces to a trace data store](/configuration/connecting-to-data-stores/jaeger), or [Tracetest directly](/configuration/connecting-to-data-stores/opentelemetry-collector). -[Follow these instructions to install OpenTelemetry in 5 minutes without any code changes!](/getting-started/no-otel.mdx) +[Follow these instructions to install OpenTelemetry in 5 minutes without any code changes!](/getting-started/no-otel) ::: diff --git a/docs/docs/core/getting-started/open.mdx b/docs/docs/core/getting-started/open.mdx index ddfec33c63..ba047c995b 100644 --- a/docs/docs/core/getting-started/open.mdx +++ b/docs/docs/core/getting-started/open.mdx @@ -1,14 +1,14 @@ --- id: open title: Opening Tracetest Core -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. Learn how to get started with creating tests once you open Tracetest. +description: Get started with opening Tracetest Core. Tracetest Core allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. Learn how to get started with creating tests once you open Tracetest. keywords: - tracetest - trace-based testing - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- This page showcases opening the Tracetest Web UI regardless if you used the Tracetest CLI, Docker, Kubernetes, or Helm to install Tracetest Server. @@ -31,7 +31,7 @@ You can create tests in two ways: This guide will show how to create end-to-end and integration tests in less than 5 minutes via the Web UI. :::note -To view the in-depth guide on creating tests visually, [check out this docs page](../../web-ui/creating-tests.md). +To view the in-depth guide on creating tests visually, [check out this docs page](/web-ui/creating-tests). ::: ### Create diff --git a/docs/docs/core/getting-started/overview.mdx b/docs/docs/core/getting-started/overview.mdx index dc95f619f0..b0f4fe72e7 100644 --- a/docs/docs/core/getting-started/overview.mdx +++ b/docs/docs/core/getting-started/overview.mdx @@ -9,7 +9,7 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- Tracetest Core is an open-source, cloud-native application, packaged and distributed as a Docker image and designed to run in a containerized environment. diff --git a/docs/docs/examples-tutorials/overview.mdx b/docs/docs/examples-tutorials/overview.mdx index 3d7068928a..991241b9f7 100644 --- a/docs/docs/examples-tutorials/overview.mdx +++ b/docs/docs/examples-tutorials/overview.mdx @@ -9,7 +9,7 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg breadcrumb_label: Nothing --- diff --git a/docs/docs/examples-tutorials/recipes.mdx b/docs/docs/examples-tutorials/recipes.mdx index 1258cf028d..aafc0dd6cd 100644 --- a/docs/docs/examples-tutorials/recipes.mdx +++ b/docs/docs/examples-tutorials/recipes.mdx @@ -1,7 +1,7 @@ --- id: recipes title: 🍱 Recipes -description: Here you can find tutorials to help you get started with Tracetest. +description: Here you can find hands-on recipes of popular use-cases to get started with Tracetest. hide_table_of_contents: false keywords: - tracetest @@ -9,7 +9,7 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg breadcrumb_label: Nothing --- @@ -19,7 +19,7 @@ If you're already building something with Tracetest, explore these Recipes. They These recipes show how to trigger Tracetest test runs with message queues like Kafka. -- [Testing Kafka in a Go API with OpenTelemetry](./recipes/testing-kafka-go-api-with-opentelemetry-tracetest.mdx) +- [Testing Kafka in a Go API with OpenTelemetry](/examples-tutorials/recipes/testing-kafka-go-api-with-opentelemetry-tracetest) ## Trace Data Stores @@ -29,65 +29,65 @@ These recipes show integrations with trace data stores and tracing vendors/provi This integration point uses the OpenTelemetry Collector as a router to send trace data to Tracetest. -- [Sending traces directly to Tracetest from a Node.js app using OpenTelemetry Collector](./recipes/running-tracetest-without-a-trace-data-store.mdx) -- [Sending traces with manual instrumentation directly to Tracetest from a Node.js app using OpenTelemetry Collector](./recipes/running-tracetest-without-a-trace-data-store-with-manual-instrumentation.md) -- [Sending traces with manual instrumentation directly to Tracetest from a Python app using OpenTelemetry Collector](./recipes/running-python-app-with-opentelemetry-collector-and-tracetest.md) +- [Sending traces directly to Tracetest from a Node.js app using OpenTelemetry Collector](/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store) +- [Sending traces with manual instrumentation directly to Tracetest from a Node.js app using OpenTelemetry Collector](/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store-with-manual-instrumentation) +- [Sending traces with manual instrumentation directly to Tracetest from a Python app using OpenTelemetry Collector](/examples-tutorials/recipes/running-python-app-with-opentelemetry-collector-and-tracetest) ### OpenTelemetry Collector + Tracing Vendors This integration point uses the OpenTelemetry Collector as a router to send trace data to both Tracetest and tracing vendors/providers. -- [Sending traces to Lightstep and Tracetest from the OpenTelemetry Demo with OpenTelemetry Collector](./recipes/running-tracetest-with-lightstep.md) -- [Sending traces to New Relic and Tracetest from the OpenTelemetry Demo with OpenTelemetry Collector](./recipes/running-tracetest-with-new-relic.md) -- [Sending traces to Datadog and Tracetest from the OpenTelemetry Demo with OpenTelemetry Collector](./recipes/running-tracetest-with-datadog.md) -- [Sending traces to Honeycomb and Tracetest from a Node.js app using the OpenTelemetry Collector](./recipes/running-tracetest-with-honeycomb.md) -- [Sending traces to Dynatrace and Tracetest from the OpenTelemetry Demo with OpenTelemetry Collector](./recipes/running-tracetest-with-dynatrace.md) -- [Sending traces to SigNoz and Tracetest from the Pokeshop API with OpenTelemetry Collector](./recipes/running-tracetest-with-signoz-pokeshop.md) +- [Sending traces to Lightstep and Tracetest from the OpenTelemetry Demo with OpenTelemetry Collector](/examples-tutorials/recipes/running-tracetest-with-lightstep) +- [Sending traces to New Relic and Tracetest from the OpenTelemetry Demo with OpenTelemetry Collector](/examples-tutorials/recipes/running-tracetest-with-new-relic) +- [Sending traces to Datadog and Tracetest from the OpenTelemetry Demo with OpenTelemetry Collector](/examples-tutorials/recipes/running-tracetest-with-datadog) +- [Sending traces to Honeycomb and Tracetest from a Node.js app using the OpenTelemetry Collector](/examples-tutorials/recipes/running-tracetest-with-honeycomb) +- [Sending traces to Dynatrace and Tracetest from the OpenTelemetry Demo with OpenTelemetry Collector](/examples-tutorials/recipes/running-tracetest-with-dynatrace) +- [Sending traces to SigNoz and Tracetest from the Pokeshop API with OpenTelemetry Collector](/examples-tutorials/recipes/running-tracetest-with-signoz-pokeshop) ### Jaeger -- [Sending traces to Jaeger from a Node.js app and fetching them from Jaeger with Tracetest](./recipes/running-tracetest-with-jaeger.md) -- [Running Tracetest on AWS Fargate with Terraform](./recipes/running-tracetest-with-aws-terraform.md) +- [Sending traces to Jaeger from a Node.js app and fetching them from Jaeger with Tracetest](/examples-tutorials/recipes/running-tracetest-with-jaeger) +- [Running Tracetest on AWS Fargate with Terraform](/examples-tutorials/recipes/running-tracetest-with-aws-terraform) ### OpenSearch -- [Sending traces to OpenSearch from a Node.js app and fetching them from OpenSearch with Tracetest](./recipes/running-tracetest-with-opensearch.md) +- [Sending traces to OpenSearch from a Node.js app and fetching them from OpenSearch with Tracetest](/examples-tutorials/recipes/running-tracetest-with-opensearch) ### Elastic -- [Sending traces to Elastic APM from a Node.js app and fetching them from Elasticsearch with Tracetest](./recipes/running-tracetest-with-elasticapm.md) +- [Sending traces to Elastic APM from a Node.js app and fetching them from Elasticsearch with Tracetest](/examples-tutorials/recipes/running-tracetest-with-elasticapm) ### Grafana Tempo -- [Sending traces to Tempo from a Node.js app and fetching them from Tempo with Tracetest](./recipes/running-tracetest-with-tempo.md) +- [Sending traces to Tempo from a Node.js app and fetching them from Tempo with Tracetest](/examples-tutorials/recipes/running-tracetest-with-tempo) ### AWS X-Ray -- [Running Tracetest with AWS X-Ray (AWS X-Ray Node.js SDK)](./recipes/running-tracetest-with-aws-x-ray.md) -- [Running Tracetest with AWS X-Ray (AWS X-Ray Node.js SDK & AWS Distro for OpenTelemetry)](./recipes/running-tracetest-with-aws-x-ray-adot.md) -- [Running Tracetest with AWS X-Ray (AWS Distro for OpenTelemetry & Pokeshop API)](./recipes/running-tracetest-with-aws-x-ray-pokeshop.md) -- [Running Tracetest with AWS Step Functions, AWS X-Ray and Terraform](./recipes/running-tracetest-with-step-functions-terraform.md) +- [Running Tracetest with AWS X-Ray (AWS X-Ray Node.js SDK)](/examples-tutorials/recipes/running-tracetest-with-aws-x-ray) +- [Running Tracetest with AWS X-Ray (AWS X-Ray Node.js SDK & AWS Distro for OpenTelemetry)](/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-adot) +- [Running Tracetest with AWS X-Ray (AWS Distro for OpenTelemetry & Pokeshop API)](/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-pokeshop) +- [Running Tracetest with AWS Step Functions, AWS X-Ray and Terraform](/examples-tutorials/recipes/running-tracetest-with-step-functions-terraform) ### Azure App Insights -- [Running Tracetest with Azure App Insights (AppInsights Otel Node.js SDK)](./recipes/running-tracetest-with-azure-app-insights.md) -- [Running Tracetest with Azure App Insights (Otel Node.js SDK & OpenTelemetry Collector)](./recipes/running-tracetest-with-azure-app-insights-collector.md) -- [Running Tracetest with Azure App Insights (OpenTelemetry Collector & Pokeshop API)](./recipes/running-tracetest-with-azure-app-insights-pokeshop.md) +- [Running Tracetest with Azure App Insights (AppInsights Otel Node.js SDK)](/examples-tutorials/recipes/running-tracetest-with-azure-app-insights) +- [Running Tracetest with Azure App Insights (Otel Node.js SDK & OpenTelemetry Collector)](/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-collector) +- [Running Tracetest with Azure App Insights (OpenTelemetry Collector & Pokeshop API)](/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-pokeshop) ## CI/CD Automation These guides show integrations with CI/CD tools. -- [GitHub Actions](../ci-cd-automation/github-actions-pipeline.md) -- [Testkube](../ci-cd-automation/testkube-pipeline.md) -- [Tekton](../ci-cd-automation/tekton-pipeline.md) +- [GitHub Actions](/ci-cd-automation/github-actions-pipeline) +- [Testkube](/ci-cd-automation/testkube-pipeline) +- [Tekton](/ci-cd-automation/tekton-pipeline) ## Tools These guides show integrations with other tools and vendors. -- [Running Tracetest with Testkube](../tools-and-integrations/testkube.md) -- [Running Tracetest with k6](../tools-and-integrations/k6.md) -- [Running Tracetest with Keptn](../tools-and-integrations/keptn.md) +- [Running Tracetest with Testkube](/tools-and-integrations/testkube) +- [Running Tracetest with k6](/tools-and-integrations/k6) +- [Running Tracetest with Keptn](/tools-and-integrations/keptn) Stay tuned! More recipes are coming soon. 🚀 diff --git a/docs/docs/examples-tutorials/recipes/running-python-app-with-opentelemetry-collector-and-tracetest.md b/docs/docs/examples-tutorials/recipes/running-python-app-with-opentelemetry-collector-and-tracetest.mdx similarity index 93% rename from docs/docs/examples-tutorials/recipes/running-python-app-with-opentelemetry-collector-and-tracetest.md rename to docs/docs/examples-tutorials/recipes/running-python-app-with-opentelemetry-collector-and-tracetest.mdx index 4b53532fa3..2c3b53bb66 100644 --- a/docs/docs/examples-tutorials/recipes/running-python-app-with-opentelemetry-collector-and-tracetest.md +++ b/docs/docs/examples-tutorials/recipes/running-python-app-with-opentelemetry-collector-and-tracetest.mdx @@ -1,4 +1,16 @@ -# Running a Python app with OpenTelemetry manual instrumention +--- +id: running-python-app-with-opentelemetry-collector-and-tracetest +title: Python with OpenTelemetry manual instrumention +description: Quick start how to configure a Python app to use OpenTelemetry instrumentation with traces, and Tracetest for enhancing your e2e and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/quick-start-python) diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-terraform.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-terraform.mdx similarity index 95% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-terraform.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-terraform.mdx index f482d309b7..6b133b6a9e 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-terraform.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-terraform.mdx @@ -1,7 +1,19 @@ -# Running Tracetest on AWS Fargate with Terraform +--- +id: running-tracetest-with-aws-terraform +title: Serverless Node.js and Jaeger with Terraform +description: Quick start on how to configure a Serverless Node.js app on AWS Lambda with OpenTelemetry traces and Tracetest for E2E and integration tests. Uses Jaeger as a trace data store and Terraform for infrastructure management. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note -[Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-aws-terraform-serverless) +[Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-aws-terraform-serverless) ::: [Tracetest](https://tracetest.io/) is a testing tool based on [OpenTelemetry](https://opentelemetry.io/) that allows you to test your distributed application. It allows you to use data from distributed traces generated by OpenTelemetry to validate and assert if your application has the desired behavior defined by your test definitions. diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-adot.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-adot.mdx similarity index 91% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-adot.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-adot.mdx index b9105959d9..0fca2e0d44 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-adot.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-adot.mdx @@ -1,4 +1,16 @@ -# Running Tracetest with AWS X-Ray (AWS X-Ray Node.js SDK & AWS Distro for OpenTelemetry) +--- +id: running-tracetest-with-aws-x-ray-adot +title: Node.js with AWS X-Ray (Node.js SDK) and AWS Distro for OpenTelemetry +description: Quick start on how to configure a Node.js app with OpenTelemetry traces, AWS X-Ray as a trace data store, including AWS Distro for OpenTelemetry, and Tracetest for enhancing your E2E and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-amazon-x-ray-adot) @@ -10,7 +22,7 @@ [AWS Distro for OpenTelemetry (ADOT)](https://aws-otel.github.io/docs/getting-started/collector) is a secure, production-ready, AWS-supported distribution of the OpenTelemetry project. Part of the Cloud Native Computing Foundation, OpenTelemetry provides open source APIs, libraries and agents to collect distributed traces and metrics for application monitoring. -## Simple Node.js API with AWS X-Ray and Tracetest +## Sample Node.js API with AWS X-Ray (Node.js SDK), AWS Distro for OpenTelemetry and Tracetest This is a simple quick start guide on how to configure a Node.js app to use instrumentation with traces and Tracetest for enhancing your E2E and integration tests with trace-based testing. The infrastructure will use AWS X-Ray as the trace data store, the ADOT as a middleware and a Node.js app to generate the telemetry data. diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-pokeshop.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-pokeshop.mdx similarity index 94% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-pokeshop.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-pokeshop.mdx index 99b2f57d0c..1756c3fdcf 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-pokeshop.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray-pokeshop.mdx @@ -1,4 +1,16 @@ -# Running Tracetest with AWS X-Ray (AWS Distro for OpenTelemetry & Pokeshop API) +--- +id: running-tracetest-with-aws-x-ray-pokeshop +title: Pokeshop API with AWS X-Ray (Node.js SDK) and AWS Distro for OpenTelemetry +description: Quick start on how to configure the Pokeshop API Demo with OpenTelemetry traces, AWS X-Ray as a trace data store, and Tracetest for enhancing your E2E and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-amazon-x-ray-pokeshop) @@ -12,7 +24,7 @@ [Pokeshop API](https://docs.tracetest.io/live-examples/pokeshop/overview) As a testing ground, the team at Tracetest has implemented a sample instrumented API around the [PokeAPI](https://pokeapi.co/). -## Pokeshop API with AWS X-Ray and Tracetest +## Pokeshop API Demo with AWS X-Ray (Node.js SDK), AWS Distro for OpenTelemetry and Tracetest This is a simple quick start guide on how to configure a fully instrumented API to be used with Tracetest for enhancing your E2E and integration tests with trace-based testing. The infrastructure will use AWS X-Ray as the trace data store, the ADOT as a middleware and the Pokeshop API to generate the telemetry data. diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray.mdx similarity index 92% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray.mdx index 9bac3b13df..f0ff3a08ce 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-aws-x-ray.mdx @@ -1,4 +1,16 @@ -# Running Tracetest with AWS X-Ray (AWS X-Ray Node.js SDK) +--- +id: running-tracetest-with-aws-x-ray +title: Node.js and AWS X-Ray (Node.js SDK) +description: Quick start on how to configure a Node.js app with OpenTelemetry traces, AWS X-Ray as a trace data store, and Tracetest for enhancing your E2E and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-amazon-x-ray) @@ -8,7 +20,7 @@ [AWS X-Ray](https://aws.amazon.com/xray/) provides a complete view of requests as they travel through your application and filters visual data across payloads, functions, traces, services, APIs and more with no-code and low-code motions. -## Sample Node.js App with AWS X-Ray and Tracetest +## Sample Node.js App with AWS X-Ray (Node.js SDK) and Tracetest This is a simple quick start guide on how to configure a Node.js app to use instrumentation with traces and Tracetest for enhancing your E2E and integration tests with trace-based testing. The infrastructure will use AWS X-Ray as the trace data store and a Node.js app to generate the telemetry data. diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-collector.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-collector.mdx similarity index 91% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-collector.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-collector.mdx index 05b5cde52c..fd10d3623e 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-collector.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-collector.mdx @@ -1,4 +1,16 @@ -# Running Tracetest with Azure App Insights (Node.js + OpenTelemetry Collector) +--- +id: running-tracetest-with-azure-app-insights-collector +title: Node.js and Azure Application Insights with OpenTelemetry Collector +description: Quick start on how to configure a Node.js app with OpenTelemetry traces, Azure Application Insights as a trace data store, including the OpenTelemetry Collector, and Tracetest for enhancing your E2E and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-azure-app-insights-collector) @@ -13,7 +25,7 @@ [OpenTelemetry Collector Contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib) - The official OpenTelemetry Distribution for packages outside of the core collector. -## Sample Node.js App with Azure App Insights, The OpenTelemetry Collector and Tracetest +## Sample Node.js App with Azure Application Insights, OpenTelemetry Collector and Tracetest This is a simple quick start guide on how to configure a Node.js app to use instrumentation with traces and Tracetest for enhancing your E2E and integration tests with trace-based testing. The infrastructure will use Azure App Insights as the trace data store, the OpenTelemetry Collector to process and route the telemetry data and a Node.js app to generate it. diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-pokeshop.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-pokeshop.mdx similarity index 93% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-pokeshop.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-pokeshop.mdx index 5829e92fe7..9e8c93b5a8 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-pokeshop.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights-pokeshop.mdx @@ -1,4 +1,16 @@ -# Running Tracetest with Azure App Insights (OpenTelemetry Collector & Pokeshop API) +--- +id: running-tracetest-with-azure-app-insights-pokeshop +title: Pokeshop API and Azure Application Insights with OpenTelemetry Collector +description: Quick start on how to configure the Pokeshop API Demo with OpenTelemetry traces, Azure Application Insights as a trace data store, including the OpenTelemetry Collector, and Tracetest for enhancing your E2E and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-azure-app-insights-pokeshop) @@ -15,7 +27,7 @@ [Pokeshop API](https://docs.tracetest.io/live-examples/pokeshop/overview) As a testing ground, the team at Tracetest has implemented a sample instrumented API around the [PokeAPI](https://pokeapi.co/). -## Pokeshop API with Azure App Insights and Tracetest +## Pokeshop API with Azure Application Insights, OpenTelemetry Collector and Tracetest This is a simple quick start guide on how to configure a fully instrumented API to be used with Tracetest for enhancing your E2E and integration tests with trace-based testing. The infrastructure will use Azure App Insights as the trace data store, the OpenTelemetry Collector as a middleware and the Pokeshop API to generate the telemetry data. @@ -31,7 +43,7 @@ The project is built with Docker Compose. ### 1. Pokeshop API -The Pokeshop API is a fully instrumented REST API that makes use of different services to mimic a real life scenario. Learn more about it, [here](../../live-examples/pokeshop/overview.md). +The Pokeshop API is a fully instrumented REST API that makes use of different services to mimic a real life scenario. Learn more about it, [here](/live-examples/pokeshop/overview). ### 2. Tracetest diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights.mdx similarity index 91% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights.mdx index ab6ccbddfe..4ebf57242b 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-azure-app-insights.mdx @@ -1,4 +1,16 @@ -# Running Tracetest with Azure App Insights (ApplicationInsights Node.js SDK) +--- +id: running-tracetest-with-azure-app-insights +title: Node.js and Azure Application Insights (Node.js SDK) +description: Quick start on how to configure a Node.js app with OpenTelemetry traces, Azure Application Insights as a trace data store, and Tracetest for enhancing your E2E and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-azure-app-insights) @@ -11,7 +23,7 @@ - Proactively understand how an application is performing. - Reactively review application execution data to determine the cause of an incident. -## Sample Node.js App with Azure App Insights and Tracetest +## Sample Node.js App with Azure Application Insights and Tracetest This is a simple quick start guide on how to configure a Node.js app to use instrumentation with traces and Tracetest for enhancing your E2E and integration tests with trace-based testing. The infrastructure will use Azure App Insights as the trace data store and a Node.js app to generate the telemetry data. diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-datadog.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-datadog.mdx similarity index 96% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-datadog.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-datadog.mdx index 2f1c7f31cd..e3c250f1a9 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-datadog.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-datadog.mdx @@ -1,4 +1,16 @@ -# Running Tracetest With Datadog +--- +id: running-tracetest-with-datadog +title: OpenTelemetry Demo and Datadog +description: Quick start how to configure the OpenTelemetry Demo to use Tracetest for enhancing your E2E and integration tests with trace-based testing with Datadog as a trace data store. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-datadog) diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-dynatrace.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-dynatrace.mdx similarity index 96% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-dynatrace.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-dynatrace.mdx index c0f67d6c2e..42ce128346 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-dynatrace.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-dynatrace.mdx @@ -1,4 +1,16 @@ -# Running Tracetest With Dynatrace +--- +id: running-tracetest-with-dynatrace +title: OpenTelemetry Demo and Dynatrace +description: Quick start how to configure the OpenTelemetry Demo to use Tracetest for enhancing your E2E and integration tests with trace-based testing with Dynatrace as a trace data store. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-dynatrace) @@ -244,7 +256,7 @@ receivers: - targets: ['0.0.0.0:8888'] processors: - batch: # this configuration is needed to guarantee that the data is sent correctly to Datadog + batch: # this configuration is needed to guarantee that the data is sent correctly to Dynatrace send_batch_max_size: 100 send_batch_size: 10 timeout: 10s diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-elasticapm.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-elasticapm.mdx similarity index 94% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-elasticapm.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-elasticapm.mdx index 0f9cca9051..1d681f7915 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-elasticapm.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-elasticapm.mdx @@ -1,4 +1,16 @@ -# Running Tracetest with Elastic APM +--- +id: running-tracetest-with-elasticapm +title: Node.js and Elastic APM +description: Quick start on how to configure a Node.js app to use Elastic APM Agent with traces and Tracetest for enhancing your E2E and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-elasticapm-with-elastic-agent) diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-honeycomb.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-honeycomb.mdx similarity index 93% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-honeycomb.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-honeycomb.mdx index e704b35571..4a1a3a61f6 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-honeycomb.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-honeycomb.mdx @@ -1,4 +1,16 @@ -# Running Tracetest With Honeycomb +--- +id: running-tracetest-with-honeycomb +title: Node.js and Honeycomb +description: Quick start how to configure the OpenTelemetry Demo to use Tracetest for enhancing your E2E and integration tests with trace-based testing with Honeycomb as a trace data store. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-honeycomb) @@ -8,6 +20,10 @@ [Honeycomb](https://honeycomb.io/) is an observability solution that shows you the patterns and outliers of how users experience your code in complex and unpredictable environments. +## Node.js App with Honeycomb, OpenTelemetry and Tracetest + +This is a quick start on how to configure a Node.js app to use OpenTelemetry instrumentation with traces, and Tracetest for enhancing your E2E and integration tests with trace-based testing and Honeycomb as a trace data store. + ## Prerequisites You will need [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/) installed on your machine to run this sample app! Additionally, you will need a Honeycomb account and api key. Sign up to use Honeycomb [here](https://ui.honeycomb.io/signup). diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-jaeger.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-jaeger.mdx similarity index 95% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-jaeger.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-jaeger.mdx index b5e72eb0d8..3f882bc551 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-jaeger.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-jaeger.mdx @@ -1,4 +1,16 @@ -# Running Tracetest with Jaeger +--- +id: running-tracetest-with-jaeger +title: Node.js and Jaeger +description: Quick start on how to configure a Node.js app with OpenTelemetry traces, Jaeger as a trace data store, and Tracetest for enhancing your E2E and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/quick-start-jaeger-nodejs) diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-lightstep.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-lightstep.mdx similarity index 96% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-lightstep.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-lightstep.mdx index dd64382aa9..123d0acaf9 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-lightstep.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-lightstep.mdx @@ -1,4 +1,16 @@ -# Running Tracetest With Lightstep +--- +id: running-tracetest-with-lightstep +title: OpenTelemetry Demo and Lightstep +description: Quick start how to configure the OpenTelemetry Demo to use Tracetest for enhancing your E2E and integration tests with trace-based testing with Lightstep as a trace data store. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-lightstep) diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-new-relic.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-new-relic.mdx similarity index 95% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-new-relic.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-new-relic.mdx index d73af65c03..5e1d80d0c0 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-new-relic.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-new-relic.mdx @@ -1,4 +1,16 @@ -# Running Tracetest With New Relic +--- +id: running-tracetest-with-new-relic +title: OpenTelemetry Demo and New Relic +description: Quick start how to configure the OpenTelemetry Demo to use Tracetest for enhancing your E2E and integration tests with trace-based testing with New Relic as a trace data store. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-new-relic) @@ -10,7 +22,7 @@ ## OpenTelemetry Demo `v0.3.4-alpha` with New Relic, OpenTelemetry and Tracetest -This is a simple sample app on how to configure the [OpenTelemetry Demo `v0.3.4-alpha`](https://github.com/open-telemetry/opentelemetry-demo) to use [Tracetest](https://tracetest.io/) for enhancing your E2E and integration tests with trace-based testing, and [New Relic](https://newrelic.com/) as a trace data store. +This is a simple sample app on how to configure the [OpenTelemetry Demo `v0.3.4-alpha`](https://github.com/open-telemetry/opentelemetry-demo) to use [Tracetest](https://tracetest.io/) for enhancing your E2E and integration tests with trace-based testing and [New Relic](https://newrelic.com/) as a trace data store. ## Prerequisites diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-opensearch.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-opensearch.mdx similarity index 95% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-opensearch.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-opensearch.mdx index f7af768cd4..28f457ff29 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-opensearch.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-opensearch.mdx @@ -1,4 +1,16 @@ -# Running Tracetest with OpenSearch +--- +id: running-tracetest-with-opensearch +title: Node.js and OpenSearch +description: Quick start on how to configure a Node.js app with OpenTelemetry traces, OpenSearch as a trace data store, and Tracetest for enhancing your E2E and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/quick-start-opensearch-nodejs) diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-signoz-pokeshop.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-signoz-pokeshop.mdx similarity index 97% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-signoz-pokeshop.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-signoz-pokeshop.mdx index 1930469218..c11c3f6173 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-signoz-pokeshop.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-signoz-pokeshop.mdx @@ -1,4 +1,16 @@ -# Running Tracetest with SigNoz (OpenTelemetry Collector & Pokeshop API) +--- +id: running-tracetest-with-signoz-pokeshop +title: Pokeshop API and SigNoz +description: Quick start how to configure the Pokeshop API Demo to use Tracetest for enhancing your E2E and integration tests with trace-based testing with SigNoz as a trace data store. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-signoz-pokeshop) @@ -10,7 +22,7 @@ [Pokeshop API](https://docs.tracetest.io/live-examples/pokeshop/overview) is a testing ground, the team at Tracetest has implemented a sample instrumented API around the [PokeAPI](https://pokeapi.co/). -## Pokeshop API with SigNoz and Tracetest +## Pokeshop API with SigNoz, OpenTelemetry and Tracetest This is a simple quick start guide on how to configure a fully instrumented API to be used with Tracetest for enhancing your E2E and integration tests with trace-based testing. The infrastructure will use SigNoz as the trace data store and the Pokeshop API to generate the telemetry data. diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-step-functions-terraform.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-step-functions-terraform.mdx similarity index 93% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-step-functions-terraform.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-step-functions-terraform.mdx index cab3ca27a7..e6fe8b0922 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-step-functions-terraform.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-step-functions-terraform.mdx @@ -1,4 +1,16 @@ -# Running Tracetest with AWS Step Functions, AWS X-Ray and Terraform +--- +id: running-tracetest-with-step-functions-terraform +title: .NET Step Functions with AWS X-Ray, AWS Distro for OpenTelemetry, and Terraform +description: Quick start on how to configure .NET step functions with OpenTelemetry traces, AWS X-Ray as a trace data store, including AWS Distro for OpenTelemetry, and Tracetest for enhancing your E2E and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/tracetest-aws-step-functions) diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-with-tempo.md b/docs/docs/examples-tutorials/recipes/running-tracetest-with-tempo.mdx similarity index 95% rename from docs/docs/examples-tutorials/recipes/running-tracetest-with-tempo.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-with-tempo.mdx index 8eb2c964f5..4ebc6b044f 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-with-tempo.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-with-tempo.mdx @@ -1,4 +1,16 @@ -# Running Tracetest with Tempo +--- +id: running-tracetest-with-tempo +title: Node.js and Grafana Tempo +description: Quick start on how to configure a Node.js app with OpenTelemetry traces, Grafana Tempo as a trace data store, and Tracetest for enhancing your E2E and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/quick-start-tempo-nodejs) diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store-with-manual-instrumentation.md b/docs/docs/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store-with-manual-instrumentation.mdx similarity index 95% rename from docs/docs/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store-with-manual-instrumentation.md rename to docs/docs/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store-with-manual-instrumentation.mdx index 87bfc0e12c..0c0aa6f5b9 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store-with-manual-instrumentation.md +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store-with-manual-instrumentation.mdx @@ -1,4 +1,16 @@ -# Running Tracetest without a Trace Data Store with Manual Instrumentation +--- +id: running-tracetest-without-a-trace-data-store-with-manual-instrumentation +title: Node.js and OpenTelemetry Manual Instrumentation +description: Quick start how to configure a Node.js app to use OpenTelemetry manual instrumentation with traces, and Tracetest for enhancing your E2E and integration tests with trace-based testing. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/quick-start-nodejs-manual-instrumentation) diff --git a/docs/docs/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store.mdx b/docs/docs/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store.mdx index 8c5831add9..207650d6d2 100644 --- a/docs/docs/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store.mdx +++ b/docs/docs/examples-tutorials/recipes/running-tracetest-without-a-trace-data-store.mdx @@ -1,7 +1,7 @@ --- id: running-tracetest-without-a-trace-data-store -title: Running Tracetest without a Trace Data Store -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. +title: Node.js and OpenTelemetry +description: Quick start how to configure a Node.js app to use OpenTelemetry instrumentation with traces, and Tracetest for enhancing your E2E and integration tests with trace-based testing. hide_table_of_contents: true keywords: - tracetest @@ -9,14 +9,13 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; - :::note [Check out the source code on GitHub here.](https://github.com/kubeshop/tracetest/tree/main/examples/quick-start-nodejs) ::: diff --git a/docs/docs/examples-tutorials/recipes/testing-kafka-go-api-with-opentelemetry-tracetest.mdx b/docs/docs/examples-tutorials/recipes/testing-kafka-go-api-with-opentelemetry-tracetest.mdx index 163f7cddd5..0448727428 100644 --- a/docs/docs/examples-tutorials/recipes/testing-kafka-go-api-with-opentelemetry-tracetest.mdx +++ b/docs/docs/examples-tutorials/recipes/testing-kafka-go-api-with-opentelemetry-tracetest.mdx @@ -1,7 +1,7 @@ --- id: testing-kafka-go-api-with-opentelemetry-tracetest title: Testing Kafka in a Go API with OpenTelemetry and Tracetest -description: Use Tracetest to run trace-based tests against Kafka in a Go API. +description: Quick start how to configure two Go APIs to communicate via Kafka. They use OpenTelemetry instrumentation with traces, Jaeger as a trace data store, and Tracetest for enhancing your E2E and integration tests with trace-based testing. hide_table_of_contents: false keywords: - tracetest @@ -9,7 +9,7 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- :::note diff --git a/docs/docs/examples-tutorials/tutorials.mdx b/docs/docs/examples-tutorials/tutorials.mdx index c39c0674f3..321cafc8bb 100644 --- a/docs/docs/examples-tutorials/tutorials.mdx +++ b/docs/docs/examples-tutorials/tutorials.mdx @@ -9,7 +9,7 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg breadcrumb_label: Nothing --- diff --git a/docs/docs/examples-tutorials/videos.mdx b/docs/docs/examples-tutorials/videos.mdx index fd3b665aca..d65edd3445 100644 --- a/docs/docs/examples-tutorials/videos.mdx +++ b/docs/docs/examples-tutorials/videos.mdx @@ -9,7 +9,7 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg breadcrumb_label: Nothing --- diff --git a/docs/docs/examples-tutorials/webinars.mdx b/docs/docs/examples-tutorials/webinars.mdx index 1038c362c9..bbe387aefb 100644 --- a/docs/docs/examples-tutorials/webinars.mdx +++ b/docs/docs/examples-tutorials/webinars.mdx @@ -9,7 +9,7 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg breadcrumb_label: Nothing --- diff --git a/docs/docs/getting-started/installation.mdx b/docs/docs/getting-started/installation.mdx index a79c2ad6e4..1538f6833c 100644 --- a/docs/docs/getting-started/installation.mdx +++ b/docs/docs/getting-started/installation.mdx @@ -1,14 +1,14 @@ --- id: installation title: Installing Tracetest -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. +description: Get started by installing Tracetest! Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. keywords: - tracetest - trace-based testing - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- import Tabs from '@theme/Tabs'; diff --git a/docs/docs/getting-started/no-otel.mdx b/docs/docs/getting-started/no-otel.mdx index 082119130a..074af2c5bd 100644 --- a/docs/docs/getting-started/no-otel.mdx +++ b/docs/docs/getting-started/no-otel.mdx @@ -2,14 +2,14 @@ id: no-otel title: What if I don't have OpenTelemetry installed? hide_table_of_contents: true -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. Learn how to install OpenTelemetry in less than 5 minutes. +description: Don't have OpenTelemetry instrumentation added in your codebase? Here's how to get started! keywords: - tracetest - trace-based testing - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- # What if I don't have OpenTelemetry installed? diff --git a/docs/docs/getting-started/open.mdx b/docs/docs/getting-started/open.mdx index a3fc806619..a532dd8dc9 100644 --- a/docs/docs/getting-started/open.mdx +++ b/docs/docs/getting-started/open.mdx @@ -1,17 +1,17 @@ --- id: open title: Opening Tracetest -description: Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. Learn how to get started with creating tests once you open Tracetest. +description: Get started with creating tests by opening Tracetest! Tracetest allows you to quickly build integration and end-to-end tests, powered by your OpenTelemetry traces. Learn how to get started with creating tests once you open Tracetest. keywords: - tracetest - trace-based testing - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- -This page showcases opening the Tracetest Web UI and creating a test against the [sample Pokeshop API](../live-examples/pokeshop/overview.md). +This page showcases opening the Tracetest Web UI and creating a test against the [sample Pokeshop API](/live-examples/pokeshop/overview). Once you've installed Tracetest, as explained in the [installation guide](./installation.mdx), the Tracetest Agent is running on `localhost` ports `4317` and `4318`. You then access the Tracetest Web UI on [`app.tracetest.io`](https://app.tracetest.io). Here's what will greet you after a fresh install. @@ -113,7 +113,7 @@ You can create tests in two ways: This guide will show how to create end-to-end and integration tests in less than 5 minutes via the Web UI. :::note -To view the in-depth guide on creating tests visually, [check out this docs page](../web-ui/creating-tests.md). +To view the in-depth guide on creating tests visually, [check out this docs page](/web-ui/creating-tests). ::: ### Create diff --git a/docs/docs/getting-started/overview.mdx b/docs/docs/getting-started/overview.mdx index bb7bf551e5..6e18e43a62 100644 --- a/docs/docs/getting-started/overview.mdx +++ b/docs/docs/getting-started/overview.mdx @@ -9,7 +9,7 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg --- Tracetest is a cloud-native application, packaged and distributed as a Docker image and designed to run in a containerized environment. diff --git a/docs/docs/index.mdx b/docs/docs/index.mdx index 85eb73fab9..49911038a3 100644 --- a/docs/docs/index.mdx +++ b/docs/docs/index.mdx @@ -9,7 +9,7 @@ keywords: - observability - distributed tracing - testing -image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg breadcrumb_label: Nothing --- diff --git a/docs/docs/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart.md b/docs/docs/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart.md index feda9da4e3..d7dcf0a0d5 100644 --- a/docs/docs/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart.md +++ b/docs/docs/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart.md @@ -35,7 +35,7 @@ It should return a payload similar to this: ## Building a Test for This Scenario -Using Tracetest, we can [create a test](../../../web-ui/creating-tests.md) that will execute an API call on `POST /api/cart` and validate the following properties: +Using Tracetest, we can [create a test](/web-ui/creating-tests) that will execute an API call on `POST /api/cart` and validate the following properties: - The correct ProductID was sent to the Product Catalog API. - The product persisted correctly on the shopping cart. @@ -46,7 +46,7 @@ Running these tests for the first time will create an Observability trace like t ### Assertions -With this trace, now we can build [assertions](../../../concepts/assertions.md) on Tracetest and validate the properties: +With this trace, now we can build [assertions](/concepts/assertions) on Tracetest and validate the properties: - **The correct ProductID was sent to the Product Catalog API.** ![](../images/add-item-into-shopping-cart-api-test-spec.png) diff --git a/docs/docs/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents.md b/docs/docs/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents.md index 68e13a2acd..702da0da2d 100644 --- a/docs/docs/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents.md +++ b/docs/docs/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents.md @@ -40,7 +40,7 @@ If it is the first time that you are calling this endpoint, to see an item into ## Building a Test for This Scenario -Using Tracetest, we can [create a test](../../../web-ui/creating-tests.md) that will execute an API call on `GET /api/cart?sessionId={some-uuid}&currecyCode=` and validate the following properties: +Using Tracetest, we can [create a test](/web-ui/creating-tests) that will execute an API call on `GET /api/cart?sessionId={some-uuid}&currecyCode=` and validate the following properties: - The product ID `66VCHSJNUP`, previously added, exists in the cart. - The size of the shopping cart should be 1. @@ -51,7 +51,7 @@ Running these tests for the first time will create an Observability trace like t ### Assertions -With this trace, now we can build [assertions](../../../concepts/assertions.md) on Tracetest and validate the properties: +With this trace, now we can build [assertions](/concepts/assertions) on Tracetest and validate the properties: - **The product ID `66VCHSJNUP`, previously added, exists in the cart.** ![](../images/check-shopping-cart-contents-product-catalog.png) diff --git a/docs/docs/live-examples/opentelemetry-store/use-cases/checkout.md b/docs/docs/live-examples/opentelemetry-store/use-cases/checkout.md index 841b9ddfb7..089602a8c0 100644 --- a/docs/docs/live-examples/opentelemetry-store/use-cases/checkout.md +++ b/docs/docs/live-examples/opentelemetry-store/use-cases/checkout.md @@ -57,7 +57,7 @@ If it is the first time that you are calling this endpoint, to see an item into ## Building a Test for This Scenario -Using Tracetest, we can [create a test](../../../web-ui/creating-tests.md) that will execute an API call on `POST /api/cart` and validate the following properties: +Using Tracetest, we can [create a test](/web-ui/creating-tests) that will execute an API call on `POST /api/cart` and validate the following properties: - An order was placed. - The user was charged. - The product was shipped. @@ -70,7 +70,7 @@ Running these tests for the first time will create an Observability trace like t ### Assertions -With this trace, now we can build [assertions](../../../concepts/assertions.md) on Tracetest and validate the properties: +With this trace, now we can build [assertions](/concepts/assertions) on Tracetest and validate the properties: - **An order was placed.** ![](../images/checkout-api-test-spec.png) diff --git a/docs/docs/live-examples/opentelemetry-store/use-cases/get-recommended-products.md b/docs/docs/live-examples/opentelemetry-store/use-cases/get-recommended-products.md index 3223d25615..8f4b2d15fd 100644 --- a/docs/docs/live-examples/opentelemetry-store/use-cases/get-recommended-products.md +++ b/docs/docs/live-examples/opentelemetry-store/use-cases/get-recommended-products.md @@ -32,7 +32,7 @@ You can trigger this use case by calling the endpoint `GET /api/recommendations? ## Building a Test for This Scenario -Using Tracetest, we can [create a test](../../../web-ui/creating-tests.md) that will execute an API call on `GET /api/recommendations?productIds=&sessionId={some-uuid}¤cyCode=` and validate the following properties: +Using Tracetest, we can [create a test](/web-ui/creating-tests) that will execute an API call on `GET /api/recommendations?productIds=&sessionId={some-uuid}¤cyCode=` and validate the following properties: - It should have 4 products on this list. - The feature flagger should be called for one product. @@ -43,7 +43,7 @@ Running these tests for the first time will create an Observability trace like t ### Assertions -With this trace, now we can build [assertions](../../../concepts/assertions.md) on Tracetest and validate the properties: +With this trace, now we can build [assertions](/concepts/assertions) on Tracetest and validate the properties: - **It should have 4 products on this list.** ![](../images/get-recommended-products-get-product-test-spec.png) diff --git a/docs/docs/live-examples/opentelemetry-store/use-cases/user-purchasing-products.md b/docs/docs/live-examples/opentelemetry-store/use-cases/user-purchasing-products.md index 1e9c30817b..1c113bb21a 100644 --- a/docs/docs/live-examples/opentelemetry-store/use-cases/user-purchasing-products.md +++ b/docs/docs/live-examples/opentelemetry-store/use-cases/user-purchasing-products.md @@ -18,11 +18,11 @@ So in this case, we need to trigger four tests in sequence to achieve test the e ## Building a Test Suite for This Scenario -Using Tracetest, we can do that by [creating a test](../../../web-ui/creating-tests.md) for each step and later grouping these tests as [Test Suites](../../../web-ui/creating-test-suites.md) that have an [variable set](../../../concepts/variable-sets.md)]. - -We can do that by creating the tests and Test Suites through the Web UI or using the CLI. In this example, we will use the CLI to create a Variable Set and then create the Test Suite with all tests needed. The [assertions](../../../concepts/assertions.md) that we will check are the same for every single test. +Using Tracetest, we can do that by [creating a test](/web-ui/creating-tests) for each step and later grouping these tests as [Test Suites](/web-ui/creating-test-suites) that have an [variable set](/concepts/variable-sets). -### Mapping Environment Variables +We can do that by creating the tests and Test Suites through the Web UI or using the CLI. In this example, we will use the CLI to create a Variable Set and then create the Test Suite with all tests needed. The [assertions](/concepts/assertions) that we will check are the same for every single test. + +### Mapping Environment Variables The first thing that we need to think about is to map the variables that are needed in this process. At first glance, we can identify the vars to the API address and the user ID: With these variables, we can create the following definition file as saving as `user-buying-products.env`: diff --git a/docs/docs/live-examples/pokeshop/use-cases/add-pokemon.md b/docs/docs/live-examples/pokeshop/use-cases/add-pokemon.md index b664ea8194..5bb5c0cbf7 100644 --- a/docs/docs/live-examples/pokeshop/use-cases/add-pokemon.md +++ b/docs/docs/live-examples/pokeshop/use-cases/add-pokemon.md @@ -43,7 +43,8 @@ It should return the following payload: ## Building a Test for This Scenario -Using Tracetest, we can [create a test](../../../web-ui/creating-tests.md) that will execute an API call on `POST /pokemon` and validate two properties: +Using Tracetest, we can [create a test](/web-ui/creating-tests) that will execute an API call on `POST /pokemon` and validate two properties: + - The API should return a proper result with **HTTP 201 Created**. - The database should return with **low latency (< 200ms)**. @@ -54,7 +55,7 @@ Running these tests for the first time will create an Observability trace like t ### Assertions -With this trace, now we can build [assertions](../../../concepts/assertions.md) on Tracetest and validate the API response and the database latency: +With this trace, now we can build [assertions](/concepts/assertions) on Tracetest and validate the API response and the database latency: - **The API should return a proper result with HTTP 201 Created:** ![](../images/add-pokemon-api-test-spec.png) diff --git a/docs/docs/live-examples/pokeshop/use-cases/get-pokemon-by-id.md b/docs/docs/live-examples/pokeshop/use-cases/get-pokemon-by-id.md index e875ee1eb5..ea616d340a 100644 --- a/docs/docs/live-examples/pokeshop/use-cases/get-pokemon-by-id.md +++ b/docs/docs/live-examples/pokeshop/use-cases/get-pokemon-by-id.md @@ -40,7 +40,8 @@ You can trigger this use case by calling the endpoint `GET /pokemon/25` without ## Building a Test for the Described Scenarios -Using Tracetest, we can [create two tests](../../../web-ui/creating-tests.md) that will execute an API call on `GET /pokemon/25` and validate the following scenarios: +Using Tracetest, we can [create two tests](/web-ui/creating-tests) that will execute an API call on `GET /pokemon/25` and validate the following scenarios: + 1. **An API call with a cache hit.** - The API should return a valid result with HTTP 200 OK. - The cache should be queried. @@ -63,7 +64,7 @@ Running these tests for the first time will create an Observability trace with t ### Assertions -With this trace, we can build [assertions](../../../concepts/assertions.md) on Tracetest and validate API, cache, and database responses: +With this trace, we can build [assertions](/concepts/assertions) on Tracetest and validate API, cache, and database responses: - [Both Cases] The API should return a valid result with HTTP 200 OK. ![](../images/get-pokemon-by-id-api-test-spec.png) diff --git a/docs/docs/live-examples/pokeshop/use-cases/import-pokemon-from-stream.md b/docs/docs/live-examples/pokeshop/use-cases/import-pokemon-from-stream.md index 0db2264215..19595bcde1 100644 --- a/docs/docs/live-examples/pokeshop/use-cases/import-pokemon-from-stream.md +++ b/docs/docs/live-examples/pokeshop/use-cases/import-pokemon-from-stream.md @@ -28,7 +28,7 @@ You can trigger this use case by sending a message to Kafka on the `pokemon` top ## Building a Test for This Scenario -Using Tracetest, we can [create a test](../../../web-ui/creating-tests.md) that will produce a message to Kafka on `pokemon` topic and validate the following properties: +Using Tracetest, we can [create a test](/web-ui/creating-tests) that will produce a message to Kafka on `pokemon` topic and validate the following properties: - The worker should read the import task. - PokeAPI should return a valid response. - The database should respond with low latency (< 200ms). @@ -41,7 +41,7 @@ Running these tests for the first time will create a distributed trace like the ### Assertions -With this trace, we can build [assertions](../../../concepts/assertions.md) with Tracetest and validate the API and Worker behavior: +With this trace, we can build [assertions](/concepts/assertions) with Tracetest and validate the API and Worker behavior: - **A message was received from Kafka stream:** ![](../images/import-pokemon-from-stream-message-received.png) diff --git a/docs/docs/live-examples/pokeshop/use-cases/import-pokemon.md b/docs/docs/live-examples/pokeshop/use-cases/import-pokemon.md index 06fdbe4575..b968dca90f 100644 --- a/docs/docs/live-examples/pokeshop/use-cases/import-pokemon.md +++ b/docs/docs/live-examples/pokeshop/use-cases/import-pokemon.md @@ -61,7 +61,7 @@ It should return the following payload: ## Building a Test for This Scenario -Using Tracetest, we can [create a test](../../../web-ui/creating-tests.md) that will execute an API call on `POST /pokemon/import` and validate the following properties: +Using Tracetest, we can [create a test](/web-ui/creating-tests) that will execute an API call on `POST /pokemon/import` and validate the following properties: - The API should enqueue an import task and return HTTP 200 OK. - The worker should dequeue the import task. - PokeAPI should return a valid response. @@ -75,7 +75,7 @@ Running these tests for the first time will create an Observability trace like t ### Assertions -With this trace, we can build [assertions](../../../concepts/assertions.md) on Tracetest and validate the API and Worker behaviors: +With this trace, we can build [assertions](/concepts/assertions) on Tracetest and validate the API and Worker behaviors: - **The API should enqueue an import task and return HTTP 200 OK:** ![](../images/import-pokemon-message-enqueue-test-spec.png) diff --git a/docs/docs/live-examples/pokeshop/use-cases/list-pokemon.md b/docs/docs/live-examples/pokeshop/use-cases/list-pokemon.md index 8440363735..5bf44e305b 100644 --- a/docs/docs/live-examples/pokeshop/use-cases/list-pokemon.md +++ b/docs/docs/live-examples/pokeshop/use-cases/list-pokemon.md @@ -39,7 +39,7 @@ You can trigger this use case by calling the endpoint `GET /pokemon?take=20&skip ## Building a Test for This Scenario -Using Tracetest, we can [create a test](../../../web-ui/creating-tests.md) that will execute an API call on `GET /pokemon` and validate three properties: +Using Tracetest, we can [create a test](/web-ui/creating-tests) that will execute an API call on `GET /pokemon` and validate three properties: - The API should return results with HTTP 200 OK. - The database should respond with low latency (< 200ms). - The database query should use the query string parameters `take` and `skip` correctly. @@ -51,7 +51,7 @@ Running these tests for the first time will create an Observability trace like t ### Assertions -With this trace, we can build [assertions](../../../concepts/assertions.md) on Tracetest and validate the API response and the database responses: +With this trace, we can build [assertions](/concepts/assertions) on Tracetest and validate the API response and the database responses: - **The API should return results with HTTP 200 OK:** ![](../images/list-pokemons-api-test-spec.png) diff --git a/docs/docs/quick-start.md b/docs/docs/quick-start.md deleted file mode 100644 index be706e6633..0000000000 --- a/docs/docs/quick-start.md +++ /dev/null @@ -1,37 +0,0 @@ -# Quick Start - -In this section, you will: -1. ... -2. ... -3. ... -4. ... - -### **1. Install the Tracetest CLI** - -... - -### **2. Scaffold Tracetest Docker config with the CLI** - -... - -### **3. Point Tracetest to a trace back end** - -... - -### **4. Run Tracetest with Docker or the CLI** - -... - -### **5. Create and run a test** - -... - -### **6. View trace and set assertions** - -... - -## Next Steps - -... - -And, if you want, connect with us on [Discord](https://discord.gg/6zupCZFQbe) to tell us about your experience! \ No newline at end of file diff --git a/docs/docs/run-affected-spans.md b/docs/docs/run-affected-spans.md deleted file mode 100644 index 11bc9e1224..0000000000 --- a/docs/docs/run-affected-spans.md +++ /dev/null @@ -1,26 +0,0 @@ -# Affected Spans - -As you might know, Tracetest assertions are composed of two main parts: -1. A selector. -2. List of checks. - -The selector is used to identify which spans will be affected by the assertion and the system can apply the different checks. -To help the process of visually identifying what spans will be affected, Tracetest highlights them and obscures the rest while either creating/editing an assertion or selecting an existing one from the test results panel. - -## Creating an Assertion -When updating the different key value pairs to narrow down the specific span, a new control will be displayed at the top left section of the Diagram view, which has the option to move across the different affected spans. - -![Affected Spans Form DAG](img/affected-spans-form-dag.png) - -At the same time, this control component will be displayed at the assertion form level; where the user has the same options to move across the affected spans and have a visual indication of what exactly is happening. - -![Affected Spans Form](img/affected-spans-form.png) - -## Selecting an Existing Assertion -By opening the Test Result bottom section, you can find the different assertions and, when clicking on any of them, the affected spans will be automatically highlighted and the controls will be displayed at the top left of the diagram. - -Selecting an Assertion -![Affected Spans Select](img/affected-spans-select.png) - -Diagram View -![Affected Spans Select](img/affected-spans-select-dag.png) \ No newline at end of file diff --git a/docs/docs/run-exports.md b/docs/docs/run-exports.md deleted file mode 100644 index 1e9ad49f32..0000000000 --- a/docs/docs/run-exports.md +++ /dev/null @@ -1,24 +0,0 @@ -# Edit a Test - -Tracetest allows you to export the different set of information displayed for assertions and checks in a way you can use it as input for other tools, create text based tests to use on your CI/CD pipelines using the CLI and more options. - -The current supported exports are: -1. JUnit results XML. -2. Test Definition YAML. - -To access any of the available exports, go to the run/trace page details for any test and, at the header level, you'll find a three dot menu which will display the options. - -![Export Trace Options](img/exports-trace-options.png) - -## JUnit Results XML -To access the JUnit XML file, select the JUnit option from the dropdown and you'll find the file viewer modal with the location to download the file. -The JUnit report contains the results from each of the assertions added to the test and their statuses. Depending on how many assertions the test has, this file will grow. - -![Export Trace JUnit](img/exports-junit.png) - -## Test Definition YAML -The Tracetest CLI allows you to execute text based tests. This means you can store all of your tests in a repo, keep track of the different versions and use them for your CI/CD process. -An easy way to start is to export the test definition directly from the UI by selecting the option from the dropdown. -The file viewer modal will popup where you can copy paste or download the file. - -![Export Trace Test Definition](img/exports-test-definition.png) \ No newline at end of file diff --git a/docs/docs/run-locally.md b/docs/docs/run-locally.md deleted file mode 100644 index 5186bce0cd..0000000000 --- a/docs/docs/run-locally.md +++ /dev/null @@ -1,92 +0,0 @@ -# Run Tracetest Locally - -Tracetest depends on a postgres database and a trace store backend (Jaeger or Tempo). The frontend requires node and npm and the backend requires the go tooling. - -## **Run on Local Kubernetes** - -Tracetest and its dependencies can be installed in a local Kubernetes cluster (microk8s, minikube, Kubernetes for Docker Desktop, etc). -Following the [install steps](./getting-started/installation) will install a running instance of Tracetest and Postgres. Installing Jaeger is the easiest way to get a trace store backend. - -The Tracetest install can be exposed with a `LoadBalancer`, `NodePort` or any similar mechanism. It can also be kept internally, only expose the Jaeger and postgres port, -and use them to run local development builds. This is useful to quickly test changes on both the front and back end. - -### **Installing Jaeger** - -Before installing Tracetest, we need to setup the [Jaeger operator](https://www.jaegertracing.io/docs/1.32/operator/), which in turn has a dependency on [cert-mnanager](https://cert-manager.io/). -cert-manager has different [install options](https://cert-manager.io/docs/installation/). The simplest way to do this is to use a static install: - -``` -$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.yaml -``` - -Once the pods in `cert-manager` namespace are running, we can install the Jaeger operator: - -``` -kubectl create namespace observability -kubectl create -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.32.0/jaeger-operator.yaml -n observability -``` - -Now, create an `AllInOne` jaeger instance: - -``` -cat < Date: Wed, 1 Nov 2023 12:58:53 -0500 Subject: [PATCH 03/19] fix(frontend): fix proto file methods parsing (#3324) --- web/src/services/Triggers/Grpc.service.ts | 25 ++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/web/src/services/Triggers/Grpc.service.ts b/web/src/services/Triggers/Grpc.service.ts index 244965fc42..ad8eb5df9f 100644 --- a/web/src/services/Triggers/Grpc.service.ts +++ b/web/src/services/Triggers/Grpc.service.ts @@ -1,4 +1,4 @@ -import {parse, NamespaceBase, Service} from 'protobufjs'; +import {parse, Namespace, ReflectionObject, Service} from 'protobufjs'; import {IRpcValues, ITriggerService} from 'types/Test.types'; import Validator from 'utils/Validator'; import GrpcRequest from 'models/GrpcRequest.model'; @@ -7,17 +7,28 @@ interface IRpcTriggerService extends ITriggerService { getMethodList(protoFile: string): string[]; } +function isService(ro: ReflectionObject): ro is Service { + return (ro as Service).methods !== undefined; +} + const RpcTriggerService = (): IRpcTriggerService => ({ getMethodList(protoFile) { const parsedData = parse(protoFile); - const methodList = parsedData.root.nestedArray.flatMap(a => { - const namespace = a as NamespaceBase; + const methodList = parsedData.root.nestedArray.flatMap(aReflection => { + if (isService(aReflection)) { + return aReflection.methodsArray; + } + + return ( + (aReflection as Namespace)?.nestedArray?.flatMap(bReflection => { + if (isService(bReflection)) { + return bReflection.methodsArray; + } - return namespace.nestedArray.flatMap(b => { - const service = b as Service; - return service.methods ? service.methodsArray : []; - }); + return []; + }) ?? [] + ); }); return methodList.reduce( From e7e8d21efa2691de1ea128b3edc3c374f45817f9 Mon Sep 17 00:00:00 2001 From: Matheus Nogueira Date: Wed, 1 Nov 2023 15:01:41 -0300 Subject: [PATCH 04/19] fix(agent): trace propagation via agent (#3328) --- agent/workers/trigger/http.go | 18 ------------------ agent/workers/trigger/instrument.go | 3 +++ 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/agent/workers/trigger/http.go b/agent/workers/trigger/http.go index 9091a1b011..b1b6d5f9ac 100644 --- a/agent/workers/trigger/http.go +++ b/agent/workers/trigger/http.go @@ -15,7 +15,6 @@ import ( "github.com/goware/urlx" "github.com/kubeshop/tracetest/server/test/trigger" "go.opentelemetry.io/otel/propagation" - "go.opentelemetry.io/otel/trace" ) func HTTP() Triggerer { @@ -38,22 +37,6 @@ func httpClient(sslVerification bool) http.Client { } } -func newSpanContext(ctx context.Context) trace.SpanContext { - spanCtx := trace.SpanContextFromContext(ctx) - tid := spanCtx.TraceID() - sid := spanCtx.SpanID() - - tracestate, _ := trace.ParseTraceState("tracetest=true") - var tf trace.TraceFlags - return trace.NewSpanContext(trace.SpanContextConfig{ - TraceID: tid, - SpanID: sid, - TraceFlags: tf.WithSampled(true), - TraceState: tracestate, - Remote: true, - }) -} - func (te *httpTriggerer) Trigger(ctx context.Context, triggerConfig trigger.Trigger, opts *Options) (Response, error) { response := Response{ Result: trigger.TriggerResult{ @@ -67,7 +50,6 @@ func (te *httpTriggerer) Trigger(ctx context.Context, triggerConfig trigger.Trig client := httpClient(triggerConfig.HTTP.SSLVerification) - ctx = trace.ContextWithSpanContext(ctx, newSpanContext(ctx)) ctx, cncl := context.WithTimeout(ctx, 30*time.Second) defer cncl() diff --git a/agent/workers/trigger/instrument.go b/agent/workers/trigger/instrument.go index 55f1755384..205ba268e9 100644 --- a/agent/workers/trigger/instrument.go +++ b/agent/workers/trigger/instrument.go @@ -39,8 +39,11 @@ func (t *instrumentedTriggerer) Trigger(ctx context.Context, triggerConfig trigg return Response{}, fmt.Errorf("could not create tracestate: %w", err) } + var tf trace.TraceFlags spanContextConfig := trace.SpanContextConfig{ TraceState: tracestate, + Remote: true, + TraceFlags: tf.WithSampled(true), } if opts != nil { From 29936fdb7325271077189b10b0540702069e3531 Mon Sep 17 00:00:00 2001 From: Sebastian Choren Date: Thu, 2 Nov 2023 21:04:43 -0300 Subject: [PATCH 05/19] feat(server): use NATS queues instead of postgres notify/listen (#3329) * feat: add nats driver * have a factory to decide which driver to use * delete postgres driver * update gomod * fix: unmarshal resolved trigger in test run --------- Co-authored-by: Matheus Nogueira --- .github/workflows/pull-request.yaml | 33 +++- docker-compose.nats.yaml | 67 +++++++ go.mod | 4 +- go.sum | 7 +- local-config/tracetest.config.nats.yaml | 24 +++ run.sh | 4 + server/app/app.go | 12 +- server/app/ds_test_connection_pipeline.go | 9 +- server/app/test_pipeline.go | 19 +- server/config/server.go | 7 + server/pkg/pipeline/factory.go | 21 +++ server/pkg/pipeline/nats_driver.go | 73 ++++++++ server/pkg/pipeline/pipeline.go | 4 +- server/pkg/pipeline/postgres_driver.go | 209 ---------------------- server/test/run_repository.go | 5 + 15 files changed, 265 insertions(+), 233 deletions(-) create mode 100644 docker-compose.nats.yaml create mode 100644 local-config/tracetest.config.nats.yaml create mode 100644 server/pkg/pipeline/factory.go create mode 100644 server/pkg/pipeline/nats_driver.go delete mode 100644 server/pkg/pipeline/postgres_driver.go diff --git a/.github/workflows/pull-request.yaml b/.github/workflows/pull-request.yaml index 94ad0b1e8a..4e451070a4 100644 --- a/.github/workflows/pull-request.yaml +++ b/.github/workflows/pull-request.yaml @@ -304,9 +304,9 @@ jobs: TEST_ENV="${{ matrix.test_env }}" \ ./run.bash || (cat /tmp/docker-log; exit 1) - trace-testing: + trace-testing-memory: needs: [build-docker] - name: Tracetesting API Server + name: Tracetesting API Server (InMemory) runs-on: ubuntu-latest steps: @@ -333,6 +333,35 @@ jobs: ./scripts/wait-for-port.sh 11633 ./run.sh tracetests || (cat /tmp/docker-log; exit 1) + trace-testing-nats: + needs: [build-docker] + name: Tracetesting API Server (NATS) + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - uses: actions/download-artifact@v3 + with: + name: tracetest-dist + path: dist/ + + - name: Import image + run: | + docker load --input dist/image.tar + + - name: Start services + run: | + ./run.sh down up + ./run.sh tracetest-logs > /tmp/docker-log & + - name: Run tests + run: | + chmod +x ./dist/tracetest ./dist/tracetest-server + + ./scripts/wait-for-port.sh 11633 + NATS=true ./run.sh tracetests || (cat /tmp/docker-log; exit 1) + e2e-cli: name: CLI e2e tests needs: [build-docker] diff --git a/docker-compose.nats.yaml b/docker-compose.nats.yaml new file mode 100644 index 0000000000..1a341f1b43 --- /dev/null +++ b/docker-compose.nats.yaml @@ -0,0 +1,67 @@ +version: "3.2" +services: + tracetest: + restart: unless-stopped + image: kubeshop/tracetest:${TAG:-latest} + extra_hosts: + - "host.docker.internal:host-gateway" + build: + context: . + volumes: + - type: bind + source: ./local-config/tracetest.config.nats.yaml + target: /app/tracetest.yaml + - type: bind + source: ./local-config/tracetest.provision.yaml + target: /app/provisioning.yaml + ports: + - 11633:11633 + command: --provisioning-file /app/provisioning.yaml + healthcheck: + test: ["CMD", "wget", "--spider", "localhost:11633"] + interval: 1s + timeout: 3s + retries: 60 + depends_on: + postgres: + condition: service_healthy + environment: + TRACETEST_DEV: ${TRACETEST_DEV} + TRACETEST_TESTPIPELINES_TRIGGEREXECUTE_ENABLED: ${TRACETEST_TESTPIPELINES_TRIGGEREXECUTE_ENABLED} + TRACETEST_TESTPIPELINES_TRACEFETCH_ENABLED: ${TRACETEST_TESTPIPELINES_TRACEFETCH_ENABLED} + TRACETEST_DATASTOREPIPELINES_TESTCONNECTION_ENABLED: ${TRACETEST_DATASTOREPIPELINES_TESTCONNECTION_ENABLED} + + postgres: + image: postgres:15.2 + environment: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + ports: + - 5432:5432 + healthcheck: + test: pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB" + interval: 1s + timeout: 5s + retries: 60 + + otel-collector: + image: otel/opentelemetry-collector-contrib:0.59.0 + extra_hosts: + - "host.docker.internal:host-gateway" + ports: + - "55679:55679" + - "4317:4317" + - "8888:8888" + command: + - "--config" + - "/otel-local-config.yaml" + volumes: + - ./local-config/collector.config.yaml:/otel-local-config.yaml + depends_on: + - tracetest + + nats: + image: nats:2.10-alpine + ports: + - "4222:4222" # connecting + - "8222:8222" # reporting server diff --git a/go.mod b/go.mod index 5812fbc6c2..25a3407036 100644 --- a/go.mod +++ b/go.mod @@ -37,11 +37,11 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/j2gg0s/otsql v0.14.0 github.com/jackc/pgx/v5 v5.4.2 - github.com/jdvr/go-again v1.0.0 github.com/jhump/protoreflect v1.12.0 github.com/json-iterator/go v1.1.12 github.com/labstack/gommon v0.3.0 github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 + github.com/nats-io/nats.go v1.31.0 github.com/ohler55/ojg v1.14.4 github.com/opensearch-project/opensearch-go v1.1.0 github.com/orlangure/gnomock v0.20.0 @@ -148,6 +148,8 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mostynb/go-grpc-compression v1.2.1 // indirect + github.com/nats-io/nkeys v0.4.5 // indirect + github.com/nats-io/nuid v1.0.1 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect diff --git a/go.sum b/go.sum index 360f503cb8..44dbc22507 100644 --- a/go.sum +++ b/go.sum @@ -1170,8 +1170,6 @@ github.com/jcmturner/gokrb5/v8 v8.4.3 h1:iTonLeSJOn7MVUtyMT+arAn5AKAPrkilzhGw8wE github.com/jcmturner/gokrb5/v8 v8.4.3/go.mod h1:dqRwJGXznQrzw6cWmyo6kH+E7jksEQG/CyVWsJEsJO0= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= -github.com/jdvr/go-again v1.0.0 h1:eNHlD8mFc9Rq7aLMKhbyaFEz68zBuU9YsfPet99dZnA= -github.com/jdvr/go-again v1.0.0/go.mod h1:QCsfhX2LgPTeaHyC7xtqQ/a5LKtAp4Ukb0eEXV8I+7M= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= @@ -1425,8 +1423,13 @@ github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5Vgl github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nats.go v1.31.0 h1:/WFBHEc/dOKBF6qf1TZhrdEfTmOZ5JzdJ+Y3m6Y/p7E= +github.com/nats-io/nats.go v1.31.0/go.mod h1:di3Bm5MLsoB4Bx61CBTsxuarI36WbhAwOm8QrW39+i8= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.4.5 h1:Zdz2BUlFm4fJlierwvGK+yl20IAKUm7eV6AAZXEhkPk= +github.com/nats-io/nkeys v0.4.5/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/neo4j/neo4j-go-driver v1.8.1-0.20200803113522-b626aa943eba/go.mod h1:ncO5VaFWh0Nrt+4KT4mOZboaczBZcLuHrG+/sUeP8gI= diff --git a/local-config/tracetest.config.nats.yaml b/local-config/tracetest.config.nats.yaml new file mode 100644 index 0000000000..be3343af64 --- /dev/null +++ b/local-config/tracetest.config.nats.yaml @@ -0,0 +1,24 @@ +postgres: + host: postgres + user: postgres + password: postgres + port: 5432 + dbname: postgres + params: sslmode=disable + +nats: + endpoint: nats:4222 + +telemetry: + exporters: + collector: + serviceName: tracetest + sampling: 100 # 100% + exporter: + type: collector + collector: + endpoint: otel-collector:4317 + +server: + telemetry: + exporter: collector diff --git a/run.sh b/run.sh index 8830aef652..41c2d58467 100755 --- a/run.sh +++ b/run.sh @@ -5,6 +5,10 @@ set -e export TAG=${TAG:-dev} opts="-f docker-compose.yaml -f examples/docker-compose.demo.yaml" +# use nats version of docker-compose if NATS is set to true +if [ "$NATS" == "true" ]; then + opts="-f docker-compose.nats.yaml -f examples/docker-compose.demo.yaml" +fi help_message() { echo "usage: ./run.sh [cypress|tracetests|up|stop|build|down|tracetest-logs|logs|ps|restart]" diff --git a/server/app/app.go b/server/app/app.go index 7e980b7323..a53ddc0e42 100644 --- a/server/app/app.go +++ b/server/app/app.go @@ -30,6 +30,7 @@ import ( "github.com/kubeshop/tracetest/server/openapi" "github.com/kubeshop/tracetest/server/otlp" "github.com/kubeshop/tracetest/server/pkg/id" + "github.com/kubeshop/tracetest/server/pkg/pipeline" "github.com/kubeshop/tracetest/server/provisioning" "github.com/kubeshop/tracetest/server/resourcemanager" "github.com/kubeshop/tracetest/server/subscription" @@ -42,6 +43,7 @@ import ( "github.com/kubeshop/tracetest/server/traces" "github.com/kubeshop/tracetest/server/variableset" "github.com/kubeshop/tracetest/server/version" + "github.com/nats-io/nats.go" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/trace" ) @@ -240,7 +242,14 @@ func (app *App) Start(opts ...appOption) error { registerOtlpServer(app, tracesRepo, runRepo, eventEmitter, dataStoreRepo, tracer) } + natsConn, err := nats.Connect(app.cfg.NATSEndpoint()) + if err != nil { + log.Printf("could not connect to NATS: %s. Defaulting to InMemory Queues", err) + } + + executorDriverFactory := pipeline.NewDriverFactory[executor.Job](natsConn) testPipeline := buildTestPipeline( + executorDriverFactory, pool, pollingProfileRepo, dataStoreRepo, @@ -274,9 +283,10 @@ func (app *App) Start(opts ...appOption) error { testSuitePipeline.Stop() }) + testConnectionDriverFactory := pipeline.NewDriverFactory[testconnection.Job](natsConn) dsTestListener := testconnection.NewListener() dsTestPipeline := buildDataStoreTestPipeline( - pool, + testConnectionDriverFactory, dsTestListener, tracer, tracedbFactory, diff --git a/server/app/ds_test_connection_pipeline.go b/server/app/ds_test_connection_pipeline.go index 536ea6faeb..8ce6a3b652 100644 --- a/server/app/ds_test_connection_pipeline.go +++ b/server/app/ds_test_connection_pipeline.go @@ -1,7 +1,6 @@ package app import ( - "github.com/jackc/pgx/v5/pgxpool" "github.com/kubeshop/tracetest/server/config" "github.com/kubeshop/tracetest/server/pkg/pipeline" "github.com/kubeshop/tracetest/server/testconnection" @@ -11,7 +10,7 @@ import ( ) func buildDataStoreTestPipeline( - pool *pgxpool.Pool, + driverFactory pipeline.DriverFactory[testconnection.Job], dsTestListener *testconnection.Listener, tracer trace.Tracer, newTraceDBFn tracedb.FactoryFunc, @@ -21,11 +20,9 @@ func buildDataStoreTestPipeline( requestWorker := testconnection.NewDsTestConnectionRequest(tracer, newTraceDBFn, appConfig.DataStorePipelineTestConnectionEnabled()) notifyWorker := testconnection.NewDsTestConnectionNotify(dsTestListener, tracer) - pgQueue := pipeline.NewPostgresQueueDriver[testconnection.Job](pool, pgChannelName) - pipeline := pipeline.New(testconnection.NewConfigurer(meter), - pipeline.Step[testconnection.Job]{Processor: requestWorker, Driver: pgQueue.Channel("datastore_test_connection_request")}, - pipeline.Step[testconnection.Job]{Processor: notifyWorker, Driver: pgQueue.Channel("datastore_test_connection_notify")}, + pipeline.Step[testconnection.Job]{Processor: requestWorker, Driver: driverFactory.NewDriver("datastore_test_connection_request")}, + pipeline.Step[testconnection.Job]{Processor: notifyWorker, Driver: driverFactory.NewDriver("datastore_test_connection_notify")}, ) return testconnection.NewDataStoreTestPipeline(pipeline, dsTestListener) diff --git a/server/app/test_pipeline.go b/server/app/test_pipeline.go index 19b4ea7e17..0f4c18aa3c 100644 --- a/server/app/test_pipeline.go +++ b/server/app/test_pipeline.go @@ -20,6 +20,7 @@ import ( ) func buildTestPipeline( + driverFactory pipeline.DriverFactory[executor.Job], pool *pgxpool.Pool, ppRepo *pollingprofile.Repository, dsRepo *datastore.Repository, @@ -123,17 +124,15 @@ func buildTestPipeline( WithInstanceID(instanceID). WithMetricMeter(meter) - pgQueue := pipeline.NewPostgresQueueDriver[executor.Job](pool, pgChannelName) - pipeline := pipeline.New(queueBuilder, - pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("trigger_resolver", triggerResolverWorker), Driver: pgQueue.Channel("trigger_resolve")}, - pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("trigger_executer", triggerExecuterWorker), Driver: pgQueue.Channel("trigger_execute")}, - pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("trigger_result_processor", triggerResultProcessorWorker), Driver: pgQueue.Channel("trigger_result")}, - pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("trace_poller_starter", tracePollerStarterWorker), Driver: pgQueue.Channel("tracePoller_start")}, - pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("trace_fetcher", traceFetcherWorker), Driver: pgQueue.Channel("tracePoller_fetch")}, - pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("trace_poller_evaluator", tracePollerEvaluatorWorker), Driver: pgQueue.Channel("tracePoller_evaluate"), InputQueueOffset: -1}, - pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("linter_runner", linterRunner), Driver: pgQueue.Channel("linterRunner")}, - pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("assertion_runner", assertionRunner), Driver: pgQueue.Channel("assertionRunner")}, + pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("trigger_resolver", triggerResolverWorker), Driver: driverFactory.NewDriver("trigger_resolve")}, + pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("trigger_executer", triggerExecuterWorker), Driver: driverFactory.NewDriver("trigger_execute")}, + pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("trigger_result_processor", triggerResultProcessorWorker), Driver: driverFactory.NewDriver("trigger_result")}, + pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("trace_poller_starter", tracePollerStarterWorker), Driver: driverFactory.NewDriver("tracePoller_start")}, + pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("trace_fetcher", traceFetcherWorker), Driver: driverFactory.NewDriver("tracePoller_fetch")}, + pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("trace_poller_evaluator", tracePollerEvaluatorWorker), Driver: driverFactory.NewDriver("tracePoller_evaluate"), InputQueueOffset: -1}, + pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("linter_runner", linterRunner), Driver: driverFactory.NewDriver("linterRunner")}, + pipeline.Step[executor.Job]{Processor: workerMetricMiddlewareBuilder.New("assertion_runner", assertionRunner), Driver: driverFactory.NewDriver("assertionRunner")}, ) const assertionRunnerStepIndex = 7 diff --git a/server/config/server.go b/server/config/server.go index d7511a7106..1f6adc91b6 100644 --- a/server/config/server.go +++ b/server/config/server.go @@ -205,3 +205,10 @@ func (c *AppConfig) AnalyticsFrontendKey() string { return c.vp.GetString("analytics.frontendKey") } + +func (c *AppConfig) NATSEndpoint() string { + c.mu.Lock() + defer c.mu.Unlock() + + return c.vp.GetString("nats.endpoint") +} diff --git a/server/pkg/pipeline/factory.go b/server/pkg/pipeline/factory.go new file mode 100644 index 0000000000..af7f821558 --- /dev/null +++ b/server/pkg/pipeline/factory.go @@ -0,0 +1,21 @@ +package pipeline + +import "github.com/nats-io/nats.go" + +func NewDriverFactory[T any](natsConn *nats.Conn) DriverFactory[T] { + return DriverFactory[T]{ + natsConn: natsConn, + } +} + +type DriverFactory[T any] struct { + natsConn *nats.Conn +} + +func (df DriverFactory[T]) NewDriver(channelName string) WorkerDriver[T] { + if df.natsConn != nil { + return NewNatsDriver[T](df.natsConn, channelName) + } + + return NewInMemoryQueueDriver[T](channelName) +} diff --git a/server/pkg/pipeline/nats_driver.go b/server/pkg/pipeline/nats_driver.go new file mode 100644 index 0000000000..b00efdfcfb --- /dev/null +++ b/server/pkg/pipeline/nats_driver.go @@ -0,0 +1,73 @@ +package pipeline + +import ( + "encoding/json" + "fmt" + + "github.com/nats-io/nats.go" +) + +type NatsDriver[T any] struct { + log loggerFn + conn *nats.Conn + topic string + subscription *nats.Subscription +} + +func NewNatsDriver[T any](conn *nats.Conn, topic string) *NatsDriver[T] { + return &NatsDriver[T]{ + log: newLoggerFn(fmt.Sprintf("NatsDriver - %s", topic)), + conn: conn, + topic: topic, + } +} + +func (d *NatsDriver[T]) Enqueue(msg T) { + msgJson, err := json.Marshal(msg) + if err != nil { + fmt.Printf("could not marshal message: %s\n", err.Error()) + } + + err = d.conn.PublishMsg(&nats.Msg{ + Subject: d.topic, + Data: msgJson, + }) + + if err != nil { + fmt.Printf("could not send publish message request: %s\n", err.Error()) + } +} + +// SetListener implements QueueDriver. +func (d *NatsDriver[T]) SetListener(listener Listener[T]) { + subscription, err := d.conn.Subscribe(d.topic, func(msg *nats.Msg) { + var target T + err := json.Unmarshal(msg.Data, &target) + if err != nil { + fmt.Printf(`could not unmarshal message got in queue "%s": %s\n`, d.topic, err.Error()) + } + + // TODO: We probably should return an error for acking or nacking this message + listener.Listen(target) + + msg.Ack() + }) + + if err != nil { + panic(err) + } + + d.subscription = subscription +} + +func (d *NatsDriver[T]) Start() { + d.log("start") +} + +func (d *NatsDriver[T]) Stop() { + err := d.subscription.Unsubscribe() + if err != nil { + d.log(`could not unsubscribe to topic "%s"\n`, d.topic) + } + d.subscription = nil +} diff --git a/server/pkg/pipeline/pipeline.go b/server/pkg/pipeline/pipeline.go index 271da9b0f8..714ed7fe77 100644 --- a/server/pkg/pipeline/pipeline.go +++ b/server/pkg/pipeline/pipeline.go @@ -20,7 +20,7 @@ type Pipeline[T any] struct { queues []*Queue[T] // N + 1 } -type workerDriver[T any] interface { +type WorkerDriver[T any] interface { QueueDriver[T] Start() Stop() @@ -40,7 +40,7 @@ type InputQueueSetter[T any] interface { } type Step[T any] struct { - Driver workerDriver[T] + Driver WorkerDriver[T] Processor StepProcessor[T] InputQueueOffset int } diff --git a/server/pkg/pipeline/postgres_driver.go b/server/pkg/pipeline/postgres_driver.go deleted file mode 100644 index d84b3f44cb..0000000000 --- a/server/pkg/pipeline/postgres_driver.go +++ /dev/null @@ -1,209 +0,0 @@ -package pipeline - -import ( - "context" - "encoding/json" - "fmt" - "time" - - "github.com/jackc/pgx/v5/pgxpool" - "github.com/jdvr/go-again" - "github.com/kubeshop/tracetest/server/pkg/id" -) - -func NewPostgresQueueDriver[T any](pool *pgxpool.Pool, channelName string) *postgresQueueDriver[T] { - id := id.GenerateID() - return &postgresQueueDriver[T]{ - log: newLoggerFn("PostgresQueueDriver - " + id.String()), - channelName: channelName, - pool: pool, - channels: map[string]*channel[T]{}, - exit: make(chan bool), - } -} - -// postgresQueueDriver is a queue driver that uses Postgres LISTEN/NOTIFY -// Since each queue needs its own connection, it's not practical/scalable -// to create a new Driver instance for each queue. Instead, we create a -// single Driver instance and use it to create channels for each queue. -// -// This driver requires one connection that listens to messages in any queue -// and routes them to the correct worker. -type postgresQueueDriver[T any] struct { - log loggerFn - channelName string - pool *pgxpool.Pool - channels map[string]*channel[T] - running bool - exit chan bool -} - -func (qd *postgresQueueDriver[T]) getChannel(name string) (*channel[T], error) { - ch, ok := qd.channels[name] - if !ok { - return nil, fmt.Errorf("channel %s not found", name) - } - - return ch, nil -} - -type pgJob[T any] struct { - Channel string `json:"channel"` - Item T `json:"job"` -} - -func (qd *postgresQueueDriver[T]) Start() { - if qd.running { - // we want only 1 worker here - qd.log("already running") - return - } - qd.running = true - - go func(qd *postgresQueueDriver[T]) { - qd.log("start") - - for { - select { - case <-qd.exit: - qd.log("exit") - return - default: - _, err := again.Retry(context.Background(), func(_ context.Context) (bool, error) { - qd.log("acquiring connection") - conn, err := qd.pool.Acquire(context.Background()) - if err != nil { - err = fmt.Errorf("error acquiring connection: %w", err) - qd.log("%s", err.Error()) - return false, err - } - defer conn.Release() - - err = qd.worker(conn) - if err != nil { - err = fmt.Errorf("error in worker: %w", err) - qd.log("%s", err.Error()) - return false, err - } - return true, nil - }) - if err != nil { - // this panic is intentional. forces the app to crash and restart - panic(err) - } - } - } - }(qd) -} - -func (qd *postgresQueueDriver[T]) worker(conn *pgxpool.Conn) error { - qd.log("listening for notifications") - _, err := conn.Exec(context.Background(), "listen "+qd.channelName) - if err != nil { - return fmt.Errorf("error listening for notifications: %w", err) - } - qd.log("waiting for notification") - notification, err := conn.Conn().WaitForNotification(context.Background()) - if err != nil { - return fmt.Errorf("error waiting for notification: %w", err) - } - - job := pgJob[T]{} - err = json.Unmarshal([]byte(notification.Payload), &job) - if err != nil { - // this error is not fatal. we can ignore it and continue - qd.log("error unmarshalling pgJob: %s", err.Error()) - return nil - } - - qd.log("received job for channel: %s", job.Channel) - - channel, err := qd.getChannel(job.Channel) - if err != nil { - // this error is not fatal. we can ignore it and continue - qd.log("error getting channel: %s", err.Error()) - return nil - } - - qd.log("processing job for channel: %s", job.Channel) - channel.listener.Listen(job.Item) - return nil -} - -func (qd *postgresQueueDriver[T]) Stop() { - qd.log("stopping") - qd.exit <- true -} - -// Channel registers a new queue channel and returns it -func (qd *postgresQueueDriver[T]) Channel(name string) *channel[T] { - if _, channelNameExists := qd.channels[name]; channelNameExists { - panic(fmt.Errorf("channel %s already exists", name)) - } - - ch := &channel[T]{ - postgresQueueDriver: qd, - name: name, - log: newLoggerFn(fmt.Sprintf("PostgresQueueDriver - %s", name)), - pool: qd.pool, - } - - qd.channels[name] = ch - - return ch -} - -type channel[T any] struct { - *postgresQueueDriver[T] - name string - log loggerFn - pool *pgxpool.Pool - listener Listener[T] -} - -func (ch *channel[T]) SetListener(l Listener[T]) { - ch.listener = l -} - -const enqueueTimeout = 5 * time.Minute - -func (ch *channel[T]) Enqueue(item T) { - ch.log("enqueue item") - - jj, err := json.Marshal(pgJob[T]{ - Channel: ch.name, - Item: item, - }) - - if err != nil { - ch.log("error marshalling pgJob: %s", err.Error()) - return - } - - ctx, cancelCtx := context.WithTimeout(context.Background(), enqueueTimeout) - defer cancelCtx() - - conn, err := again.Retry[*pgxpool.Conn](ctx, func(ctx context.Context) (*pgxpool.Conn, error) { - ch.log("trying to acquire connection") - return ch.pool.Acquire(context.Background()) - }) - - if err != nil { - ch.log("error acquiring connection: %s", err.Error()) - return - } - ch.log("acquired connection for") - defer conn.Release() - - _, err = conn.Query(ctx, fmt.Sprintf(`select pg_notify('%s', $1)`, ch.postgresQueueDriver.channelName), jj) - if err != nil { - ch.log("error notifying postgres: %s", err.Error()) - return - } - - ch.log("notified postgres") -} - -func (ch *channel[T]) Name() string { - return ch.name -} diff --git a/server/test/run_repository.go b/server/test/run_repository.go index 0cd7497566..3a836f49c9 100644 --- a/server/test/run_repository.go +++ b/server/test/run_repository.go @@ -655,6 +655,11 @@ func readRunRow(row scanner) (Run, error) { return Run{}, fmt.Errorf("cannot parse TriggerResult: %w", err) } + err = json.Unmarshal(jsonResolvedTrigger, &r.ResolvedTrigger) + if err != nil { + return Run{}, fmt.Errorf("cannot parse ResolvedTrigger: %w", err) + } + err = json.Unmarshal(jsonTestResults, &r.Results) if err != nil { return Run{}, fmt.Errorf("cannot parse Results: %w", err) From 95b3ef304d3dff4738d0b8eedc1832f23b60c8ab Mon Sep 17 00:00:00 2001 From: Oscar Reyes Date: Thu, 2 Nov 2023 18:36:48 -0600 Subject: [PATCH 06/19] chore(UI): Updating Otel Demo Proto (#3332) --- web/src/constants/Demo.constants.ts | 10 +++++----- web/src/constants/demos/otel-demo.proto.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/web/src/constants/Demo.constants.ts b/web/src/constants/Demo.constants.ts index f322b357c3..fa16db8037 100644 --- a/web/src/constants/Demo.constants.ts +++ b/web/src/constants/Demo.constants.ts @@ -205,7 +205,7 @@ export function getOtelDemo(demoSettings: Demo) { name: 'Otel - List Products', url: otelProductCatalog, message: '', - method: 'hipstershop.ProductCatalogService.ListProducts', + method: 'oteldemo.ProductCatalogService.ListProducts', description: 'Otel - List Products', protoFile: otelProtoFile, }, @@ -213,7 +213,7 @@ export function getOtelDemo(demoSettings: Demo) { name: 'Otel - Get Product', url: otelProductCatalog, message: '{"id": "OLJCESPC7Z"}', - method: 'hipstershop.ProductCatalogService.GetProduct', + method: 'oteldemo.ProductCatalogService.GetProduct', description: 'Otel - Get Product', protoFile: otelProtoFile, }, @@ -221,7 +221,7 @@ export function getOtelDemo(demoSettings: Demo) { name: 'Otel - Add To Cart', url: otelCart, message: JSON.stringify({item: {product_id: 'OLJCESPC7Z', quantity: 1}, user_id: userId}), - method: 'hipstershop.CartService.AddItem', + method: 'oteldemo.CartService.AddItem', description: 'Otel - Add To Cart', protoFile: otelProtoFile, }, @@ -229,7 +229,7 @@ export function getOtelDemo(demoSettings: Demo) { name: 'Otel - Get Cart', url: otelCart, message: `{"user_id": "${userId}"}`, - method: 'hipstershop.CartService.GetCart', + method: 'oteldemo.CartService.GetCart', description: 'Otel - Get Cart', protoFile: otelProtoFile, }, @@ -254,7 +254,7 @@ export function getOtelDemo(demoSettings: Demo) { credit_card_expiration_month: 1, }, }), - method: 'hipstershop.CheckoutService.PlaceOrder', + method: 'oteldemo.CheckoutService.PlaceOrder', description: 'Otel - Checkout', protoFile: otelProtoFile, }, diff --git a/web/src/constants/demos/otel-demo.proto.ts b/web/src/constants/demos/otel-demo.proto.ts index 80d4013598..34aa63cba9 100644 --- a/web/src/constants/demos/otel-demo.proto.ts +++ b/web/src/constants/demos/otel-demo.proto.ts @@ -4,5 +4,5 @@ */ export default { proto: - 'syntax = "proto3";\n\nimport "google/protobuf/timestamp.proto";\n\npackage hipstershop;\n\noption go_package = "genproto/hipstershop";\n\n\n\nservice CartService {\n rpc AddItem(AddItemRequest) returns (Empty) {}\n rpc GetCart(GetCartRequest) returns (Cart) {}\n rpc EmptyCart(EmptyCartRequest) returns (Empty) {}\n}\n\nmessage CartItem {\n string product_id = 1;\n int32 quantity = 2;\n}\n\nmessage AddItemRequest {\n string user_id = 1;\n CartItem item = 2;\n}\n\nmessage EmptyCartRequest {\n string user_id = 1;\n}\n\nmessage GetCartRequest {\n string user_id = 1;\n}\n\nmessage Cart {\n string user_id = 1;\n repeated CartItem items = 2;\n}\n\nmessage Empty {}\n\n\n\nservice RecommendationService {\n rpc ListRecommendations(ListRecommendationsRequest) returns (ListRecommendationsResponse){}\n}\n\nmessage ListRecommendationsRequest {\n string user_id = 1;\n repeated string product_ids = 2;\n}\n\nmessage ListRecommendationsResponse {\n repeated string product_ids = 1;\n}\n\n\n\nservice ProductCatalogService {\n rpc ListProducts(Empty) returns (ListProductsResponse) {}\n rpc GetProduct(GetProductRequest) returns (Product) {}\n rpc SearchProducts(SearchProductsRequest) returns (SearchProductsResponse) {}\n}\n\nmessage Product {\n string id = 1;\n string name = 2;\n string description = 3;\n string picture = 4;\n Money price_usd = 5;\n\n\n\n repeated string categories = 6;\n}\n\nmessage ListProductsResponse {\n repeated Product products = 1;\n}\n\nmessage GetProductRequest {\n string id = 1;\n}\n\nmessage SearchProductsRequest {\n string query = 1;\n}\n\nmessage SearchProductsResponse {\n repeated Product results = 1;\n}\n\n\n\nservice ShippingService {\n rpc GetQuote(GetQuoteRequest) returns (GetQuoteResponse) {}\n rpc ShipOrder(ShipOrderRequest) returns (ShipOrderResponse) {}\n}\n\nmessage GetQuoteRequest {\n Address address = 1;\n repeated CartItem items = 2;\n}\n\nmessage GetQuoteResponse {\n Money cost_usd = 1;\n}\n\nmessage ShipOrderRequest {\n Address address = 1;\n repeated CartItem items = 2;\n}\n\nmessage ShipOrderResponse {\n string tracking_id = 1;\n}\n\nmessage Address {\n string street_address = 1;\n string city = 2;\n string state = 3;\n string country = 4;\n int32 zip_code = 5;\n}\n\n\n\nservice CurrencyService {\n rpc GetSupportedCurrencies(Empty) returns (GetSupportedCurrenciesResponse) {}\n rpc Convert(CurrencyConversionRequest) returns (Money) {}\n}\n\n\nmessage Money {\n\n string currency_code = 1;\n\n\n\n int64 units = 2;\n\n\n\n\n\n\n\n int32 nanos = 3;\n}\n\nmessage GetSupportedCurrenciesResponse {\n\n repeated string currency_codes = 1;\n}\n\nmessage CurrencyConversionRequest {\n Money from = 1;\n\n\n string to_code = 2;\n}\n\n\n\nservice PaymentService {\n rpc Charge(ChargeRequest) returns (ChargeResponse) {}\n}\n\nmessage CreditCardInfo {\n string credit_card_number = 1;\n int32 credit_card_cvv = 2;\n int32 credit_card_expiration_year = 3;\n int32 credit_card_expiration_month = 4;\n}\n\nmessage ChargeRequest {\n Money amount = 1;\n CreditCardInfo credit_card = 2;\n}\n\nmessage ChargeResponse {\n string transaction_id = 1;\n}\n\n\n\nservice EmailService {\n rpc SendOrderConfirmation(SendOrderConfirmationRequest) returns (Empty) {}\n}\n\nmessage OrderItem {\n CartItem item = 1;\n Money cost = 2;\n}\n\nmessage OrderResult {\n string order_id = 1;\n string shipping_tracking_id = 2;\n Money shipping_cost = 3;\n Address shipping_address = 4;\n repeated OrderItem items = 5;\n}\n\nmessage SendOrderConfirmationRequest {\n string email = 1;\n OrderResult order = 2;\n}\n\n\n\n\nservice CheckoutService {\n rpc PlaceOrder(PlaceOrderRequest) returns (PlaceOrderResponse) {}\n}\n\nmessage PlaceOrderRequest {\n string user_id = 1;\n string user_currency = 2;\n\n Address address = 3;\n string email = 5;\n CreditCardInfo credit_card = 6;\n}\n\nmessage PlaceOrderResponse {\n OrderResult order = 1;\n}\n\n\n\nservice AdService {\n rpc GetAds(AdRequest) returns (AdResponse) {}\n}\n\nmessage AdRequest {\n\n repeated string context_keys = 1;\n}\n\nmessage AdResponse {\n repeated Ad ads = 1;\n}\n\nmessage Ad {\n\n string redirect_url = 1;\n\n\n string text = 2;\n}\n\n\n\nservice FeatureFlagService {\n rpc GetFlag(GetFlagRequest) returns (GetFlagResponse) {}\n rpc CreateFlag(CreateFlagRequest) returns (CreateFlagResponse) {}\n rpc UpdateFlag(UpdateFlagRequest) returns (UpdateFlagResponse) {}\n rpc ListFlags(ListFlagsRequest) returns (ListFlagsResponse) {}\n rpc DeleteFlag(DeleteFlagRequest) returns (DeleteFlagResponse) {}\n}\n\nmessage Flag {\n string name = 1;\n string description = 2;\n bool enabled = 3;\n google.protobuf.Timestamp created_at = 4;\n google.protobuf.Timestamp updated_at = 5;\n}\n\nmessage GetFlagRequest {\n string name = 1;\n}\n\nmessage GetFlagResponse {\n Flag flag = 1;\n}\n\nmessage CreateFlagRequest {\n string name = 1;\n string description = 2;\n bool enabled = 3;\n}\n\nmessage CreateFlagResponse {\n Flag flag = 1;\n}\n\nmessage UpdateFlagRequest {\n string name = 1;\n bool enabled = 2;\n}\n\nmessage UpdateFlagResponse {}\n\nmessage ListFlagsRequest {}\n\nmessage ListFlagsResponse {\n repeated Flag flag = 1;\n}\n\nmessage DeleteFlagRequest {\n string name = 1;\n}\n\nmessage DeleteFlagResponse {}\n', + 'syntax = "proto3";\n\nimport "google/protobuf/timestamp.proto";\n\npackage oteldemo;\n\noption go_package = "genproto/oteldemo";\n\n\n\nservice CartService {\n rpc AddItem(AddItemRequest) returns (Empty) {}\n rpc GetCart(GetCartRequest) returns (Cart) {}\n rpc EmptyCart(EmptyCartRequest) returns (Empty) {}\n}\n\nmessage CartItem {\n string product_id = 1;\n int32 quantity = 2;\n}\n\nmessage AddItemRequest {\n string user_id = 1;\n CartItem item = 2;\n}\n\nmessage EmptyCartRequest {\n string user_id = 1;\n}\n\nmessage GetCartRequest {\n string user_id = 1;\n}\n\nmessage Cart {\n string user_id = 1;\n repeated CartItem items = 2;\n}\n\nmessage Empty {}\n\n\n\nservice RecommendationService {\n rpc ListRecommendations(ListRecommendationsRequest) returns (ListRecommendationsResponse){}\n}\n\nmessage ListRecommendationsRequest {\n string user_id = 1;\n repeated string product_ids = 2;\n}\n\nmessage ListRecommendationsResponse {\n repeated string product_ids = 1;\n}\n\n\n\nservice ProductCatalogService {\n rpc ListProducts(Empty) returns (ListProductsResponse) {}\n rpc GetProduct(GetProductRequest) returns (Product) {}\n rpc SearchProducts(SearchProductsRequest) returns (SearchProductsResponse) {}\n}\n\nmessage Product {\n string id = 1;\n string name = 2;\n string description = 3;\n string picture = 4;\n Money price_usd = 5;\n\n\n\n repeated string categories = 6;\n}\n\nmessage ListProductsResponse {\n repeated Product products = 1;\n}\n\nmessage GetProductRequest {\n string id = 1;\n}\n\nmessage SearchProductsRequest {\n string query = 1;\n}\n\nmessage SearchProductsResponse {\n repeated Product results = 1;\n}\n\n\n\nservice ShippingService {\n rpc GetQuote(GetQuoteRequest) returns (GetQuoteResponse) {}\n rpc ShipOrder(ShipOrderRequest) returns (ShipOrderResponse) {}\n}\n\nmessage GetQuoteRequest {\n Address address = 1;\n repeated CartItem items = 2;\n}\n\nmessage GetQuoteResponse {\n Money cost_usd = 1;\n}\n\nmessage ShipOrderRequest {\n Address address = 1;\n repeated CartItem items = 2;\n}\n\nmessage ShipOrderResponse {\n string tracking_id = 1;\n}\n\nmessage Address {\n string street_address = 1;\n string city = 2;\n string state = 3;\n string country = 4;\n int32 zip_code = 5;\n}\n\n\n\nservice CurrencyService {\n rpc GetSupportedCurrencies(Empty) returns (GetSupportedCurrenciesResponse) {}\n rpc Convert(CurrencyConversionRequest) returns (Money) {}\n}\n\n\nmessage Money {\n\n string currency_code = 1;\n\n\n\n int64 units = 2;\n\n\n\n\n\n\n\n int32 nanos = 3;\n}\n\nmessage GetSupportedCurrenciesResponse {\n\n repeated string currency_codes = 1;\n}\n\nmessage CurrencyConversionRequest {\n Money from = 1;\n\n\n string to_code = 2;\n}\n\n\n\nservice PaymentService {\n rpc Charge(ChargeRequest) returns (ChargeResponse) {}\n}\n\nmessage CreditCardInfo {\n string credit_card_number = 1;\n int32 credit_card_cvv = 2;\n int32 credit_card_expiration_year = 3;\n int32 credit_card_expiration_month = 4;\n}\n\nmessage ChargeRequest {\n Money amount = 1;\n CreditCardInfo credit_card = 2;\n}\n\nmessage ChargeResponse {\n string transaction_id = 1;\n}\n\n\n\nservice EmailService {\n rpc SendOrderConfirmation(SendOrderConfirmationRequest) returns (Empty) {}\n}\n\nmessage OrderItem {\n CartItem item = 1;\n Money cost = 2;\n}\n\nmessage OrderResult {\n string order_id = 1;\n string shipping_tracking_id = 2;\n Money shipping_cost = 3;\n Address shipping_address = 4;\n repeated OrderItem items = 5;\n}\n\nmessage SendOrderConfirmationRequest {\n string email = 1;\n OrderResult order = 2;\n}\n\n\n\n\nservice CheckoutService {\n rpc PlaceOrder(PlaceOrderRequest) returns (PlaceOrderResponse) {}\n}\n\nmessage PlaceOrderRequest {\n string user_id = 1;\n string user_currency = 2;\n\n Address address = 3;\n string email = 5;\n CreditCardInfo credit_card = 6;\n}\n\nmessage PlaceOrderResponse {\n OrderResult order = 1;\n}\n\n\n\nservice AdService {\n rpc GetAds(AdRequest) returns (AdResponse) {}\n}\n\nmessage AdRequest {\n\n repeated string context_keys = 1;\n}\n\nmessage AdResponse {\n repeated Ad ads = 1;\n}\n\nmessage Ad {\n\n string redirect_url = 1;\n\n\n string text = 2;\n}\n\n\n\nservice FeatureFlagService {\n rpc GetFlag(GetFlagRequest) returns (GetFlagResponse) {}\n rpc CreateFlag(CreateFlagRequest) returns (CreateFlagResponse) {}\n rpc UpdateFlag(UpdateFlagRequest) returns (UpdateFlagResponse) {}\n rpc ListFlags(ListFlagsRequest) returns (ListFlagsResponse) {}\n rpc DeleteFlag(DeleteFlagRequest) returns (DeleteFlagResponse) {}\n}\n\nmessage Flag {\n string name = 1;\n string description = 2;\n bool enabled = 3;\n google.protobuf.Timestamp created_at = 4;\n google.protobuf.Timestamp updated_at = 5;\n}\n\nmessage GetFlagRequest {\n string name = 1;\n}\n\nmessage GetFlagResponse {\n Flag flag = 1;\n}\n\nmessage CreateFlagRequest {\n string name = 1;\n string description = 2;\n bool enabled = 3;\n}\n\nmessage CreateFlagResponse {\n Flag flag = 1;\n}\n\nmessage UpdateFlagRequest {\n string name = 1;\n bool enabled = 2;\n}\n\nmessage UpdateFlagResponse {}\n\nmessage ListFlagsRequest {}\n\nmessage ListFlagsResponse {\n repeated Flag flag = 1;\n}\n\nmessage DeleteFlagRequest {\n string name = 1;\n}\n\nmessage DeleteFlagResponse {}\n', }; From 944c0ca7fd29ffdcb4bdd1276e2ca8af09269a55 Mon Sep 17 00:00:00 2001 From: kdhamric Date: Thu, 2 Nov 2023 20:34:22 -0500 Subject: [PATCH 07/19] try-live-demos (#3316) * try-live-demos Docs to try the live demos * Update try-live-demos.mdx needs an s at the end of try-live-demos * docs(livedemos): misc edits and cleanuo * Update try-live-demos.mdx Slight edit --------- Co-authored-by: Adnan Rahic --- docs/docs/getting-started/try-live-demos.mdx | 32 +++++++++++++++++++ .../opentelemetry-store/overview.md | 6 ++++ docs/docs/live-examples/pokeshop/overview.md | 6 ++++ docs/sidebars.js | 7 +++- 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 docs/docs/getting-started/try-live-demos.mdx diff --git a/docs/docs/getting-started/try-live-demos.mdx b/docs/docs/getting-started/try-live-demos.mdx new file mode 100644 index 0000000000..6546b72049 --- /dev/null +++ b/docs/docs/getting-started/try-live-demos.mdx @@ -0,0 +1,32 @@ +--- +id: try-live-demos +title: Try Live Demos! +description: Tracetest has . +keywords: + - tracetest + - trace-based testing + - opentelemetry store demo + - open telemetry demo + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1689693872/docs/Blog_Thumbnail_28_ugy2yy.png +--- + +Tracetest has two shared demo environments which allow you to view, create, and run tests. Playing with these is a great way to get started learning to use Tracetest. *Hint, hint... it is really easy!* 😉 + +## OpenTelemetry Astronomy Shop Demo + +The official [demo of the OpenTelemetry project](https://github.com/open-telemetry/opentelemetry-demo)! + +👉 **Join our [shared OpenTelemetry Demo environment](https://app.tracetest.io/organizations/ttorg_2179a9cd8ba8dfa5/invites/invite_646747b36e9ee487/accept).** + +Once you join, check out the [live examples of the OpenTelemetry Demo store](/live-examples/opentelemetry-store/overview/). + + +## Pokeshop API Demo + +Tracetest has fun microservice app built using nodejs. Has two services, and RabbitMQ communicating between them. + +👉 **Join our [shared Pokeshop API Demo environment](https://app.tracetest.io/organizations/ttorg_2179a9cd8ba8dfa5/invites/invite_760904a64b4b9dc9/accept).** + +Once you join, check out the [live examples of the Pokeshop API Demo](/live-examples/pokeshop/overview). + diff --git a/docs/docs/live-examples/opentelemetry-store/overview.md b/docs/docs/live-examples/opentelemetry-store/overview.md index f15c34075e..e7156a220e 100644 --- a/docs/docs/live-examples/opentelemetry-store/overview.md +++ b/docs/docs/live-examples/opentelemetry-store/overview.md @@ -2,6 +2,12 @@ The OpenTelemetry Demo is an example application published by the OpenTelemtry CNCF project. It implements an Astronomy shop in a set of microservices in different languages with OpenTelemetry enabled, intended to be used as an example of OpenTelemetry instrumentation and observability. The Tracetest team has made several key contributions to this project, including providing a full suite of end to end tests. +:::info +Want to run tests against the OpenTelemetry Astronomy Shop without installing it? Click the link below and we will add you to our `tracetest-demo` organization and give you access to the `opentelemetry-demo` org as an engineer. You can run and create your own tests! + +[👉 **Access the shared demo, here.**](https://app.tracetest.io/organizations/ttorg_2179a9cd8ba8dfa5/invites/invite_646747b36e9ee487/accept) +::: + We will provide a full recipe below for running the full demo as well as running the associated Tracetests via Docker. Here are other references you may find useful: - **Source Code**: https://github.com/open-telemetry/opentelemetry-demo diff --git a/docs/docs/live-examples/pokeshop/overview.md b/docs/docs/live-examples/pokeshop/overview.md index 8d27784152..cb15581633 100644 --- a/docs/docs/live-examples/pokeshop/overview.md +++ b/docs/docs/live-examples/pokeshop/overview.md @@ -6,6 +6,12 @@ The idea is to have a microservice-divided system that behaves like a typical sc With this, users can get familiar with the Tracetest tool by focusing on creating assertions, visualizing the trace and identifying the different data that comes from the Collector ([Jaeger](https://www.jaegertracing.io/)). Users will learn about basic instrumentation practices: what tools to use, what data to send, when, and what suggested standards need to be followed. +:::info +Want to run tests against the Pokeshop Demo without installing it locally? Click the link below and we will add you to our `tracetest-demo` organization and give you access to the `pokeshop-demo` org as an engineer. You can run and create your own tests! + +[👉 **Access the shared demo, here.**](https://app.tracetest.io/organizations/ttorg_2179a9cd8ba8dfa5/invites/invite_760904a64b4b9dc9/accept) +::: + - **Source Code**: https://github.com/kubeshop/pokeshop - **Running it locally**: [Instructions](https://github.com/kubeshop/pokeshop/blob/master/docs/installing.md#run-it-locally) - **Running on Kubernetes**: [Instructions](https://github.com/kubeshop/pokeshop/blob/master/docs/installing.md#run-on-a-kubernetes-cluster) diff --git a/docs/sidebars.js b/docs/sidebars.js index 16808acd6d..943c71af3d 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -67,7 +67,7 @@ const sidebars = { }, { type: "category", - label: "Pokemon API Demo", + label: "Pokeshop API Demo", items: [ { type: "doc", @@ -463,6 +463,11 @@ const sidebars = { id: "getting-started/no-otel", label: "What if I don't have OpenTelemetry installed?", }, + { + type: "doc", + id: "getting-started/try-live-demos", + label: "Try live demos!", + }, ], }, { From e146b2c0d65eb4654db3cddc6007b66f58364d4d Mon Sep 17 00:00:00 2001 From: Matheus Nogueira Date: Fri, 3 Nov 2023 15:17:06 -0300 Subject: [PATCH 08/19] fix(agent): send error message to server in case of failures (#3334) --- agent/proto/orchestrator.pb.go | 1077 +++++++++++++++++--------------- agent/proto/orchestrator.proto | 6 + agent/workers/poller.go | 23 + agent/workers/poller_test.go | 41 ++ agent/workers/trigger.go | 23 + agent/workers/trigger_test.go | 45 ++ 6 files changed, 719 insertions(+), 496 deletions(-) diff --git a/agent/proto/orchestrator.pb.go b/agent/proto/orchestrator.pb.go index b3ceb32617..863e590f82 100644 --- a/agent/proto/orchestrator.pb.go +++ b/agent/proto/orchestrator.pb.go @@ -1143,6 +1143,7 @@ type TriggerResult struct { Grpc *GrpcResponse `protobuf:"bytes,3,opt,name=grpc,proto3" json:"grpc,omitempty"` TraceID *TraceIdResponse `protobuf:"bytes,4,opt,name=traceID,proto3" json:"traceID,omitempty"` Kafka *KafkaResponse `protobuf:"bytes,5,opt,name=kafka,proto3" json:"kafka,omitempty"` + Error *Error `protobuf:"bytes,6,opt,name=error,proto3" json:"error,omitempty"` } func (x *TriggerResult) Reset() { @@ -1212,6 +1213,13 @@ func (x *TriggerResult) GetKafka() *KafkaResponse { return nil } +func (x *TriggerResult) GetError() *Error { + if x != nil { + return x.Error + } + return nil +} + type HttpResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1393,6 +1401,53 @@ func (x *TraceIdResponse) GetId() string { return "" } +type Error struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *Error) Reset() { + *x = Error{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_orchestrator_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Error) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Error) ProtoMessage() {} + +func (x *Error) ProtoReflect() protoreflect.Message { + mi := &file_proto_orchestrator_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Error.ProtoReflect.Descriptor instead. +func (*Error) Descriptor() ([]byte, []int) { + return file_proto_orchestrator_proto_rawDescGZIP(), []int{22} +} + +func (x *Error) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + type DataStoreConnectionTestRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1405,7 +1460,7 @@ type DataStoreConnectionTestRequest struct { func (x *DataStoreConnectionTestRequest) Reset() { *x = DataStoreConnectionTestRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[22] + mi := &file_proto_orchestrator_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1418,7 +1473,7 @@ func (x *DataStoreConnectionTestRequest) String() string { func (*DataStoreConnectionTestRequest) ProtoMessage() {} func (x *DataStoreConnectionTestRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[22] + mi := &file_proto_orchestrator_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1431,7 +1486,7 @@ func (x *DataStoreConnectionTestRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DataStoreConnectionTestRequest.ProtoReflect.Descriptor instead. func (*DataStoreConnectionTestRequest) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{22} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{23} } func (x *DataStoreConnectionTestRequest) GetRequestID() string { @@ -1462,7 +1517,7 @@ type DataStoreConnectionTestResponse struct { func (x *DataStoreConnectionTestResponse) Reset() { *x = DataStoreConnectionTestResponse{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[23] + mi := &file_proto_orchestrator_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1475,7 +1530,7 @@ func (x *DataStoreConnectionTestResponse) String() string { func (*DataStoreConnectionTestResponse) ProtoMessage() {} func (x *DataStoreConnectionTestResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[23] + mi := &file_proto_orchestrator_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1488,7 +1543,7 @@ func (x *DataStoreConnectionTestResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DataStoreConnectionTestResponse.ProtoReflect.Descriptor instead. func (*DataStoreConnectionTestResponse) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{23} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{24} } func (x *DataStoreConnectionTestResponse) GetRequestID() string { @@ -1533,7 +1588,7 @@ type DataStoreConnectionTestSteps struct { func (x *DataStoreConnectionTestSteps) Reset() { *x = DataStoreConnectionTestSteps{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[24] + mi := &file_proto_orchestrator_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1546,7 +1601,7 @@ func (x *DataStoreConnectionTestSteps) String() string { func (*DataStoreConnectionTestSteps) ProtoMessage() {} func (x *DataStoreConnectionTestSteps) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[24] + mi := &file_proto_orchestrator_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1559,7 +1614,7 @@ func (x *DataStoreConnectionTestSteps) ProtoReflect() protoreflect.Message { // Deprecated: Use DataStoreConnectionTestSteps.ProtoReflect.Descriptor instead. func (*DataStoreConnectionTestSteps) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{24} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{25} } func (x *DataStoreConnectionTestSteps) GetPortCheck() *DataStoreConnectionTestStep { @@ -1604,7 +1659,7 @@ type DataStoreConnectionTestStep struct { func (x *DataStoreConnectionTestStep) Reset() { *x = DataStoreConnectionTestStep{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[25] + mi := &file_proto_orchestrator_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1617,7 +1672,7 @@ func (x *DataStoreConnectionTestStep) String() string { func (*DataStoreConnectionTestStep) ProtoMessage() {} func (x *DataStoreConnectionTestStep) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[25] + mi := &file_proto_orchestrator_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1630,7 +1685,7 @@ func (x *DataStoreConnectionTestStep) ProtoReflect() protoreflect.Message { // Deprecated: Use DataStoreConnectionTestStep.ProtoReflect.Descriptor instead. func (*DataStoreConnectionTestStep) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{25} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{26} } func (x *DataStoreConnectionTestStep) GetPassed() bool { @@ -1676,7 +1731,7 @@ type PollingRequest struct { func (x *PollingRequest) Reset() { *x = PollingRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[26] + mi := &file_proto_orchestrator_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1689,7 +1744,7 @@ func (x *PollingRequest) String() string { func (*PollingRequest) ProtoMessage() {} func (x *PollingRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[26] + mi := &file_proto_orchestrator_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1702,7 +1757,7 @@ func (x *PollingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PollingRequest.ProtoReflect.Descriptor instead. func (*PollingRequest) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{26} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{27} } func (x *PollingRequest) GetRequestID() string { @@ -1758,7 +1813,7 @@ type DataStore struct { func (x *DataStore) Reset() { *x = DataStore{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[27] + mi := &file_proto_orchestrator_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1771,7 +1826,7 @@ func (x *DataStore) String() string { func (*DataStore) ProtoMessage() {} func (x *DataStore) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[27] + mi := &file_proto_orchestrator_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1784,7 +1839,7 @@ func (x *DataStore) ProtoReflect() protoreflect.Message { // Deprecated: Use DataStore.ProtoReflect.Descriptor instead. func (*DataStore) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{27} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{28} } func (x *DataStore) GetType() string { @@ -1854,7 +1909,7 @@ type JaegerConfig struct { func (x *JaegerConfig) Reset() { *x = JaegerConfig{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[28] + mi := &file_proto_orchestrator_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1867,7 +1922,7 @@ func (x *JaegerConfig) String() string { func (*JaegerConfig) ProtoMessage() {} func (x *JaegerConfig) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[28] + mi := &file_proto_orchestrator_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1880,7 +1935,7 @@ func (x *JaegerConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use JaegerConfig.ProtoReflect.Descriptor instead. func (*JaegerConfig) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{28} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{29} } func (x *JaegerConfig) GetGrpc() *GrpcClientSettings { @@ -1903,7 +1958,7 @@ type TempoConfig struct { func (x *TempoConfig) Reset() { *x = TempoConfig{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[29] + mi := &file_proto_orchestrator_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1916,7 +1971,7 @@ func (x *TempoConfig) String() string { func (*TempoConfig) ProtoMessage() {} func (x *TempoConfig) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[29] + mi := &file_proto_orchestrator_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1929,7 +1984,7 @@ func (x *TempoConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use TempoConfig.ProtoReflect.Descriptor instead. func (*TempoConfig) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{29} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{30} } func (x *TempoConfig) GetType() string { @@ -1969,7 +2024,7 @@ type ElasticConfig struct { func (x *ElasticConfig) Reset() { *x = ElasticConfig{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[30] + mi := &file_proto_orchestrator_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1982,7 +2037,7 @@ func (x *ElasticConfig) String() string { func (*ElasticConfig) ProtoMessage() {} func (x *ElasticConfig) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[30] + mi := &file_proto_orchestrator_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1995,7 +2050,7 @@ func (x *ElasticConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use ElasticConfig.ProtoReflect.Descriptor instead. func (*ElasticConfig) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{30} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{31} } func (x *ElasticConfig) GetAddresses() []string { @@ -2052,7 +2107,7 @@ type SignalfxConfig struct { func (x *SignalfxConfig) Reset() { *x = SignalfxConfig{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[31] + mi := &file_proto_orchestrator_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2065,7 +2120,7 @@ func (x *SignalfxConfig) String() string { func (*SignalfxConfig) ProtoMessage() {} func (x *SignalfxConfig) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[31] + mi := &file_proto_orchestrator_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2078,7 +2133,7 @@ func (x *SignalfxConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use SignalfxConfig.ProtoReflect.Descriptor instead. func (*SignalfxConfig) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{31} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{32} } func (x *SignalfxConfig) GetRealm() string { @@ -2110,7 +2165,7 @@ type AwsXRayConfig struct { func (x *AwsXRayConfig) Reset() { *x = AwsXRayConfig{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[32] + mi := &file_proto_orchestrator_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2123,7 +2178,7 @@ func (x *AwsXRayConfig) String() string { func (*AwsXRayConfig) ProtoMessage() {} func (x *AwsXRayConfig) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[32] + mi := &file_proto_orchestrator_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2136,7 +2191,7 @@ func (x *AwsXRayConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use AwsXRayConfig.ProtoReflect.Descriptor instead. func (*AwsXRayConfig) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{32} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{33} } func (x *AwsXRayConfig) GetRegion() string { @@ -2188,7 +2243,7 @@ type AzureAppInsightsConfig struct { func (x *AzureAppInsightsConfig) Reset() { *x = AzureAppInsightsConfig{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[33] + mi := &file_proto_orchestrator_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2201,7 +2256,7 @@ func (x *AzureAppInsightsConfig) String() string { func (*AzureAppInsightsConfig) ProtoMessage() {} func (x *AzureAppInsightsConfig) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[33] + mi := &file_proto_orchestrator_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2214,7 +2269,7 @@ func (x *AzureAppInsightsConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use AzureAppInsightsConfig.ProtoReflect.Descriptor instead. func (*AzureAppInsightsConfig) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{33} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{34} } func (x *AzureAppInsightsConfig) GetUseAzureActiveDirectoryAuth() bool { @@ -2259,7 +2314,7 @@ type HttpClientSettings struct { func (x *HttpClientSettings) Reset() { *x = HttpClientSettings{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[34] + mi := &file_proto_orchestrator_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2272,7 +2327,7 @@ func (x *HttpClientSettings) String() string { func (*HttpClientSettings) ProtoMessage() {} func (x *HttpClientSettings) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[34] + mi := &file_proto_orchestrator_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2285,7 +2340,7 @@ func (x *HttpClientSettings) ProtoReflect() protoreflect.Message { // Deprecated: Use HttpClientSettings.ProtoReflect.Descriptor instead. func (*HttpClientSettings) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{34} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{35} } func (x *HttpClientSettings) GetUrl() string { @@ -2335,7 +2390,7 @@ type GrpcClientSettings struct { func (x *GrpcClientSettings) Reset() { *x = GrpcClientSettings{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[35] + mi := &file_proto_orchestrator_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2348,7 +2403,7 @@ func (x *GrpcClientSettings) String() string { func (*GrpcClientSettings) ProtoMessage() {} func (x *GrpcClientSettings) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[35] + mi := &file_proto_orchestrator_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2361,7 +2416,7 @@ func (x *GrpcClientSettings) ProtoReflect() protoreflect.Message { // Deprecated: Use GrpcClientSettings.ProtoReflect.Descriptor instead. func (*GrpcClientSettings) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{35} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{36} } func (x *GrpcClientSettings) GetEndpoint() string { @@ -2441,7 +2496,7 @@ type TLS struct { func (x *TLS) Reset() { *x = TLS{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[36] + mi := &file_proto_orchestrator_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2454,7 +2509,7 @@ func (x *TLS) String() string { func (*TLS) ProtoMessage() {} func (x *TLS) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[36] + mi := &file_proto_orchestrator_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2467,7 +2522,7 @@ func (x *TLS) ProtoReflect() protoreflect.Message { // Deprecated: Use TLS.ProtoReflect.Descriptor instead. func (*TLS) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{36} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{37} } func (x *TLS) GetInsecure() bool { @@ -2513,7 +2568,7 @@ type TLSSetting struct { func (x *TLSSetting) Reset() { *x = TLSSetting{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[37] + mi := &file_proto_orchestrator_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2526,7 +2581,7 @@ func (x *TLSSetting) String() string { func (*TLSSetting) ProtoMessage() {} func (x *TLSSetting) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[37] + mi := &file_proto_orchestrator_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2539,7 +2594,7 @@ func (x *TLSSetting) ProtoReflect() protoreflect.Message { // Deprecated: Use TLSSetting.ProtoReflect.Descriptor instead. func (*TLSSetting) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{37} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{38} } func (x *TLSSetting) GetCAFile() string { @@ -2589,12 +2644,13 @@ type PollingResponse struct { TraceID string `protobuf:"bytes,5,opt,name=traceID,proto3" json:"traceID,omitempty"` Spans []*Span `protobuf:"bytes,6,rep,name=spans,proto3" json:"spans,omitempty"` TraceFound bool `protobuf:"varint,7,opt,name=traceFound,proto3" json:"traceFound,omitempty"` + Error *Error `protobuf:"bytes,8,opt,name=error,proto3" json:"error,omitempty"` } func (x *PollingResponse) Reset() { *x = PollingResponse{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[38] + mi := &file_proto_orchestrator_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2607,7 +2663,7 @@ func (x *PollingResponse) String() string { func (*PollingResponse) ProtoMessage() {} func (x *PollingResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[38] + mi := &file_proto_orchestrator_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2620,7 +2676,7 @@ func (x *PollingResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PollingResponse.ProtoReflect.Descriptor instead. func (*PollingResponse) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{38} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{39} } func (x *PollingResponse) GetRequestID() string { @@ -2672,6 +2728,13 @@ func (x *PollingResponse) GetTraceFound() bool { return false } +func (x *PollingResponse) GetError() *Error { + if x != nil { + return x.Error + } + return nil +} + type Span struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2689,7 +2752,7 @@ type Span struct { func (x *Span) Reset() { *x = Span{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[39] + mi := &file_proto_orchestrator_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2702,7 +2765,7 @@ func (x *Span) String() string { func (*Span) ProtoMessage() {} func (x *Span) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[39] + mi := &file_proto_orchestrator_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2715,7 +2778,7 @@ func (x *Span) ProtoReflect() protoreflect.Message { // Deprecated: Use Span.ProtoReflect.Descriptor instead. func (*Span) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{39} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{40} } func (x *Span) GetId() string { @@ -2779,7 +2842,7 @@ type KeyValuePair struct { func (x *KeyValuePair) Reset() { *x = KeyValuePair{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[40] + mi := &file_proto_orchestrator_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2792,7 +2855,7 @@ func (x *KeyValuePair) String() string { func (*KeyValuePair) ProtoMessage() {} func (x *KeyValuePair) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[40] + mi := &file_proto_orchestrator_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2805,7 +2868,7 @@ func (x *KeyValuePair) ProtoReflect() protoreflect.Message { // Deprecated: Use KeyValuePair.ProtoReflect.Descriptor instead. func (*KeyValuePair) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{40} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{41} } func (x *KeyValuePair) GetKey() string { @@ -2839,7 +2902,7 @@ type KafkaRequest struct { func (x *KafkaRequest) Reset() { *x = KafkaRequest{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[41] + mi := &file_proto_orchestrator_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2852,7 +2915,7 @@ func (x *KafkaRequest) String() string { func (*KafkaRequest) ProtoMessage() {} func (x *KafkaRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[41] + mi := &file_proto_orchestrator_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2865,7 +2928,7 @@ func (x *KafkaRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use KafkaRequest.ProtoReflect.Descriptor instead. func (*KafkaRequest) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{41} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{42} } func (x *KafkaRequest) GetBrokerUrls() []string { @@ -2929,7 +2992,7 @@ type KafkaAuthentication struct { func (x *KafkaAuthentication) Reset() { *x = KafkaAuthentication{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[42] + mi := &file_proto_orchestrator_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2942,7 +3005,7 @@ func (x *KafkaAuthentication) String() string { func (*KafkaAuthentication) ProtoMessage() {} func (x *KafkaAuthentication) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[42] + mi := &file_proto_orchestrator_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2955,7 +3018,7 @@ func (x *KafkaAuthentication) ProtoReflect() protoreflect.Message { // Deprecated: Use KafkaAuthentication.ProtoReflect.Descriptor instead. func (*KafkaAuthentication) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{42} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{43} } func (x *KafkaAuthentication) GetType() string { @@ -2984,7 +3047,7 @@ type KafkaPlainAuthentication struct { func (x *KafkaPlainAuthentication) Reset() { *x = KafkaPlainAuthentication{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[43] + mi := &file_proto_orchestrator_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2997,7 +3060,7 @@ func (x *KafkaPlainAuthentication) String() string { func (*KafkaPlainAuthentication) ProtoMessage() {} func (x *KafkaPlainAuthentication) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[43] + mi := &file_proto_orchestrator_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3010,7 +3073,7 @@ func (x *KafkaPlainAuthentication) ProtoReflect() protoreflect.Message { // Deprecated: Use KafkaPlainAuthentication.ProtoReflect.Descriptor instead. func (*KafkaPlainAuthentication) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{43} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{44} } func (x *KafkaPlainAuthentication) GetUsername() string { @@ -3039,7 +3102,7 @@ type KafkaResponse struct { func (x *KafkaResponse) Reset() { *x = KafkaResponse{} if protoimpl.UnsafeEnabled { - mi := &file_proto_orchestrator_proto_msgTypes[44] + mi := &file_proto_orchestrator_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3052,7 +3115,7 @@ func (x *KafkaResponse) String() string { func (*KafkaResponse) ProtoMessage() {} func (x *KafkaResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_orchestrator_proto_msgTypes[44] + mi := &file_proto_orchestrator_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3065,7 +3128,7 @@ func (x *KafkaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use KafkaResponse.ProtoReflect.Descriptor instead. func (*KafkaResponse) Descriptor() ([]byte, []int) { - return file_proto_orchestrator_proto_rawDescGZIP(), []int{44} + return file_proto_orchestrator_proto_rawDescGZIP(), []int{45} } func (x *KafkaResponse) GetPartition() string { @@ -3213,7 +3276,7 @@ var file_proto_orchestrator_proto_rawDesc = []byte{ 0x0d, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x0d, 0x74, 0x72, 0x69, 0x67, - 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xd3, 0x01, 0x0a, 0x0d, 0x54, 0x72, + 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xf7, 0x01, 0x0a, 0x0d, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, @@ -3226,332 +3289,339 @@ var file_proto_orchestrator_proto_rawDesc = []byte{ 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, 0x12, 0x2a, 0x0a, 0x05, 0x6b, 0x61, 0x66, 0x6b, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4b, 0x61, 0x66, 0x6b, 0x61, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x6b, 0x61, 0x66, 0x6b, 0x61, 0x22, - 0x87, 0x01, 0x0a, 0x0c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x07, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x71, 0x0a, 0x0c, 0x47, 0x72, 0x70, - 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x72, 0x70, 0x63, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x08, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x21, 0x0a, 0x0f, - 0x54, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, - 0x6e, 0x0a, 0x1e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x12, - 0x2e, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, - 0xe8, 0x01, 0x0a, 0x1f, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, - 0x6c, 0x12, 0x4c, 0x0a, 0x13, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x39, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, - 0x65, 0x70, 0x73, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x22, 0xba, 0x02, 0x0a, 0x1c, 0x44, - 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x40, 0x0a, 0x09, 0x70, - 0x6f, 0x72, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, - 0x65, 0x70, 0x52, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x46, 0x0a, - 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, - 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x4a, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x6b, 0x61, 0x66, 0x6b, 0x61, 0x12, + 0x22, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x22, 0x87, 0x01, 0x0a, 0x0c, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, + 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x43, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2b, 0x0a, 0x07, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, + 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x71, 0x0a, + 0x0c, 0x47, 0x72, 0x70, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2d, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x72, 0x70, 0x63, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, + 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, + 0x22, 0x21, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x22, 0x21, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x6e, 0x0a, 0x1e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, + 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x12, 0x2e, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x09, 0x64, 0x61, 0x74, + 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0xe8, 0x01, 0x0a, 0x1f, 0x44, 0x61, 0x74, 0x61, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, + 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x12, 0x4c, 0x0a, 0x13, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x13, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, + 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, + 0x73, 0x22, 0xba, 0x02, 0x0a, 0x1c, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, + 0x70, 0x73, 0x12, 0x40, 0x0a, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, + 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x12, 0x46, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x0c, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x4a, 0x0a, 0x0e, + 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, + 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, + 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0b, 0x66, 0x65, 0x74, 0x63, + 0x68, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, - 0x70, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x44, 0x0a, 0x0b, 0x66, 0x65, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, - 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x0b, 0x66, 0x65, 0x74, 0x63, - 0x68, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x22, 0x7d, 0x0a, 0x1b, 0x44, 0x61, 0x74, 0x61, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, - 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xa6, 0x01, 0x0a, 0x0e, 0x50, 0x6f, 0x6c, 0x6c, 0x69, - 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x65, 0x73, 0x74, 0x49, - 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x65, 0x73, 0x74, 0x49, 0x44, 0x12, - 0x14, 0x0a, 0x05, 0x72, 0x75, 0x6e, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, - 0x72, 0x75, 0x6e, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, 0x12, - 0x2e, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, - 0x90, 0x03, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x6a, 0x61, 0x65, 0x67, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4a, 0x61, 0x65, 0x67, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x6a, 0x61, 0x65, 0x67, 0x65, 0x72, 0x12, 0x28, - 0x0a, 0x05, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x05, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x12, 0x34, 0x0a, 0x0a, 0x6f, 0x70, 0x65, 0x6e, - 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x34, - 0x0a, 0x0a, 0x65, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, 0x61, 0x70, 0x6d, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6c, 0x61, 0x73, 0x74, - 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x65, 0x6c, 0x61, 0x73, 0x74, 0x69, - 0x63, 0x61, 0x70, 0x6d, 0x12, 0x31, 0x0a, 0x08, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x66, 0x78, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, - 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x66, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x66, 0x78, 0x12, 0x2e, 0x0a, 0x07, 0x61, 0x77, 0x73, 0x78, 0x72, - 0x61, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x41, 0x77, 0x73, 0x58, 0x52, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, - 0x61, 0x77, 0x73, 0x78, 0x72, 0x61, 0x79, 0x12, 0x49, 0x0a, 0x10, 0x61, 0x7a, 0x75, 0x72, 0x65, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, - 0x70, 0x70, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x10, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x73, 0x69, 0x67, 0x68, - 0x74, 0x73, 0x22, 0x3d, 0x0a, 0x0c, 0x4a, 0x61, 0x65, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x2d, 0x0a, 0x04, 0x67, 0x72, 0x70, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x72, 0x70, 0x63, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x04, 0x67, 0x72, 0x70, - 0x63, 0x22, 0x7f, 0x0a, 0x0b, 0x54, 0x65, 0x6d, 0x70, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x04, 0x68, - 0x74, 0x74, 0x70, 0x12, 0x2d, 0x0a, 0x04, 0x67, 0x72, 0x70, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x72, 0x70, 0x63, 0x43, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x04, 0x67, 0x72, - 0x70, 0x63, 0x22, 0xcd, 0x01, 0x0a, 0x0d, 0x45, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, - 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, - 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x6b, - 0x69, 0x70, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, - 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, 0x69, - 0x66, 0x79, 0x22, 0x3c, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x66, 0x78, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x6c, 0x6d, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x61, 0x6c, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x22, 0xbf, 0x01, 0x0a, 0x0d, 0x41, 0x77, 0x73, 0x58, 0x52, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, - 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x75, 0x73, - 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x75, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0e, 0x75, 0x73, 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x75, - 0x74, 0x68, 0x22, 0xca, 0x01, 0x0a, 0x16, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x70, 0x70, 0x49, - 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x40, 0x0a, - 0x1b, 0x75, 0x73, 0x65, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x41, 0x75, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1b, 0x75, 0x73, 0x65, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x41, 0x75, 0x74, 0x68, 0x12, - 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, - 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x72, 0x6d, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x72, 0x6d, 0x49, 0x64, 0x22, - 0xb4, 0x01, 0x0a, 0x12, 0x48, 0x74, 0x74, 0x70, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, - 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x2b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x07, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x03, 0x74, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x52, 0x03, - 0x74, 0x6c, 0x73, 0x12, 0x41, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xe6, 0x02, 0x0a, 0x12, 0x47, 0x72, 0x70, 0x63, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a, 0x0a, - 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x61, - 0x64, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x0e, 0x72, 0x65, 0x61, 0x64, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, - 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, - 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x77, 0x72, 0x69, 0x74, - 0x65, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x77, - 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, - 0x2b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x70, 0x52, 0x0b, 0x66, 0x65, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x22, 0x7d, + 0x0a, 0x1b, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x12, 0x16, 0x0a, + 0x06, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, + 0x61, 0x73, 0x73, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xa6, 0x01, + 0x0a, 0x0e, 0x50, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x12, 0x16, + 0x0a, 0x06, 0x74, 0x65, 0x73, 0x74, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x74, 0x65, 0x73, 0x74, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x75, 0x6e, 0x49, 0x44, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x75, 0x6e, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, + 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, 0x12, 0x2e, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x09, 0x64, 0x61, 0x74, + 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x90, 0x03, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x06, 0x6a, 0x61, 0x65, 0x67, + 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x4a, 0x61, 0x65, 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x6a, + 0x61, 0x65, 0x67, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x05, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x65, 0x6d, + 0x70, 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x05, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x12, + 0x34, 0x0a, 0x0a, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6c, 0x61, 0x73, + 0x74, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x6e, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x34, 0x0a, 0x0a, 0x65, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, + 0x61, 0x70, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x45, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x0a, 0x65, 0x6c, 0x61, 0x73, 0x74, 0x69, 0x63, 0x61, 0x70, 0x6d, 0x12, 0x31, 0x0a, 0x08, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x66, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x66, 0x78, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x66, 0x78, 0x12, 0x2e, + 0x0a, 0x07, 0x61, 0x77, 0x73, 0x78, 0x72, 0x61, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x77, 0x73, 0x58, 0x52, 0x61, 0x79, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x07, 0x61, 0x77, 0x73, 0x78, 0x72, 0x61, 0x79, 0x12, 0x49, + 0x0a, 0x10, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x73, 0x69, 0x67, 0x68, + 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, + 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x61, 0x70, + 0x70, 0x69, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x3d, 0x0a, 0x0c, 0x4a, 0x61, 0x65, + 0x67, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2d, 0x0a, 0x04, 0x67, 0x72, 0x70, + 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x47, 0x72, 0x70, 0x63, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x52, 0x04, 0x67, 0x72, 0x70, 0x63, 0x22, 0x7f, 0x0a, 0x0b, 0x54, 0x65, 0x6d, 0x70, + 0x6f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x68, + 0x74, 0x74, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x2d, 0x0a, 0x04, 0x67, 0x72, + 0x70, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x47, 0x72, 0x70, 0x63, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x73, 0x52, 0x04, 0x67, 0x72, 0x70, 0x63, 0x22, 0xcd, 0x01, 0x0a, 0x0d, 0x45, 0x6c, + 0x61, 0x73, 0x74, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x69, 0x6e, 0x73, + 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, + 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x22, 0x3c, 0x0a, 0x0e, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x66, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x72, + 0x65, 0x61, 0x6c, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x61, 0x6c, + 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xbf, 0x01, 0x0a, 0x0d, 0x41, 0x77, 0x73, 0x58, + 0x52, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, + 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x49, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, + 0x79, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, + 0x63, 0x72, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, + 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x75, 0x73, 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, + 0x75, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x75, 0x73, 0x65, 0x44, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x41, 0x75, 0x74, 0x68, 0x22, 0xca, 0x01, 0x0a, 0x16, 0x41, 0x7a, + 0x75, 0x72, 0x65, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x73, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x40, 0x0a, 0x1b, 0x75, 0x73, 0x65, 0x41, 0x7a, 0x75, 0x72, 0x65, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x41, + 0x75, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x75, 0x73, 0x65, 0x41, 0x7a, + 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x41, 0x75, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x24, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x72, 0x6d, 0x49, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x41, 0x72, 0x6d, 0x49, 0x64, 0x22, 0xb4, 0x01, 0x0a, 0x12, 0x48, 0x74, 0x74, 0x70, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, + 0x2b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x22, 0x0a, 0x0c, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x03, 0x74, 0x6c, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x52, 0x03, 0x74, 0x6c, 0x73, - 0x12, 0x2d, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x41, 0x75, 0x74, 0x68, 0x65, - 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, - 0xa0, 0x01, 0x0a, 0x03, 0x54, 0x4c, 0x53, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, - 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, - 0x75, 0x72, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, - 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x12, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, - 0x69, 0x66, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, - 0x53, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, - 0x67, 0x73, 0x22, 0x9a, 0x01, 0x0a, 0x0a, 0x54, 0x4c, 0x53, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, - 0x67, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x41, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x63, 0x41, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x65, 0x72, - 0x74, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x65, 0x72, - 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x46, 0x69, 0x6c, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x46, 0x69, 0x6c, 0x65, 0x12, - 0x1e, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x1e, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, - 0x88, 0x02, 0x0a, 0x0f, 0x50, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x44, 0x12, 0x4c, 0x0a, 0x13, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x16, 0x0a, 0x06, 0x74, 0x65, 0x73, 0x74, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x74, 0x65, 0x73, 0x74, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x75, 0x6e, 0x49, 0x44, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x75, 0x6e, 0x49, 0x44, 0x12, 0x18, 0x0a, - 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, 0x12, 0x21, 0x0a, 0x05, 0x73, 0x70, 0x61, 0x6e, 0x73, - 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, - 0x70, 0x61, 0x6e, 0x52, 0x05, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x72, - 0x61, 0x63, 0x65, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0xc7, 0x01, 0x0a, 0x04, 0x53, - 0x70, 0x61, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, - 0x33, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x07, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4b, 0x65, 0x79, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x22, 0x36, 0x0a, 0x0c, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x50, 0x61, 0x69, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa5, 0x02, 0x0a, - 0x0c, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, - 0x0a, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x73, 0x12, 0x14, 0x0a, - 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, - 0x70, 0x69, 0x63, 0x12, 0x42, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x73, 0x6c, 0x56, 0x65, - 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0f, 0x73, 0x73, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x2d, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, - 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, - 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x22, 0x60, 0x0a, 0x13, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x41, 0x75, 0x74, - 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, - 0x35, 0x0a, 0x05, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x50, 0x6c, 0x61, 0x69, - 0x6e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x05, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x22, 0x52, 0x0a, 0x18, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x50, - 0x6c, 0x61, 0x69, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, - 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x45, 0x0a, 0x0d, 0x4b, 0x61, - 0x66, 0x6b, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, - 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, - 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, - 0x74, 0x32, 0xb6, 0x05, 0x0a, 0x0c, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, - 0x6f, 0x72, 0x12, 0x3d, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x15, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, - 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x00, 0x12, 0x4d, 0x0a, 0x14, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x69, - 0x67, 0x67, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x72, - 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x00, 0x30, 0x01, - 0x12, 0x3b, 0x0a, 0x11, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x72, - 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x0c, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x4c, 0x0a, - 0x13, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x41, + 0x64, 0x65, 0x72, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x03, + 0x74, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x52, 0x03, 0x74, 0x6c, 0x73, 0x12, 0x41, 0x0a, 0x0e, 0x61, 0x75, + 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x41, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x61, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xe6, 0x02, + 0x0a, 0x12, 0x47, 0x72, 0x70, 0x63, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x61, 0x64, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, + 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x72, 0x65, 0x61, 0x64, 0x42, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x53, 0x69, + 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x61, + 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x77, 0x61, 0x69, 0x74, 0x46, 0x6f, + 0x72, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x2b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x48, 0x74, 0x74, 0x70, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x72, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, + 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x03, 0x74, 0x6c, 0x73, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, + 0x4c, 0x53, 0x52, 0x03, 0x74, 0x6c, 0x73, 0x12, 0x2d, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x74, + 0x74, 0x70, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0xa0, 0x01, 0x0a, 0x03, 0x54, 0x4c, 0x53, 0x12, 0x1a, + 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x69, 0x6e, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x53, 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x53, 0x6b, 0x69, 0x70, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x4c, 0x53, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x9a, 0x01, 0x0a, 0x0a, 0x54, 0x4c, + 0x53, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x41, 0x46, 0x69, + 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x41, 0x46, 0x69, 0x6c, 0x65, + 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x63, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x6b, 0x65, 0x79, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, + 0x65, 0x79, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x69, 0x6e, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xac, 0x02, 0x0a, 0x0f, 0x50, 0x6f, 0x6c, 0x6c, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44, 0x12, 0x4c, 0x0a, 0x13, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x13, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x65, 0x73, 0x74, 0x49, 0x44, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x65, 0x73, 0x74, 0x49, 0x44, 0x12, 0x14, + 0x0a, 0x05, 0x72, 0x75, 0x6e, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, + 0x75, 0x6e, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, 0x12, 0x21, + 0x0a, 0x05, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x52, 0x05, 0x73, 0x70, 0x61, 0x6e, + 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x46, 0x6f, 0x75, 0x6e, + 0x64, 0x12, 0x22, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xc7, 0x01, 0x0a, 0x04, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, + 0x0a, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, + 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, + 0x61, 0x69, 0x72, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, + 0x36, 0x0a, 0x0c, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x61, 0x69, 0x72, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa5, 0x02, 0x0a, 0x0c, 0x4b, 0x61, 0x66, 0x6b, + 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x72, 0x6f, 0x6b, + 0x65, 0x72, 0x55, 0x72, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x72, + 0x6f, 0x6b, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, + 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x42, + 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4b, + 0x61, 0x66, 0x6b, 0x61, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x73, 0x6c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x73, 0x73, 0x6c, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x07, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x61, + 0x69, 0x72, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x60, 0x0a, 0x13, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x35, 0x0a, 0x05, 0x70, 0x6c, + 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x41, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x70, 0x6c, 0x61, 0x69, + 0x6e, 0x22, 0x52, 0x0a, 0x18, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x41, + 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x45, 0x0a, 0x0d, 0x4b, 0x61, 0x66, 0x6b, 0x61, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x32, 0xb6, 0x05, 0x0a, + 0x0c, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x3d, 0x0a, + 0x07, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x14, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x39, 0x0a, 0x0f, 0x53, - 0x65, 0x6e, 0x64, 0x50, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x16, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x18, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, - 0x65, 0x72, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x16, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x04, 0x50, 0x69, - 0x6e, 0x67, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x0c, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x6d, - 0x0a, 0x24, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, - 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, - 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, - 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, - 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5b, 0x0a, - 0x21, 0x53, 0x65, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, - 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x73, 0x68, 0x6f, - 0x70, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x11, 0x53, + 0x65, 0x6e, 0x64, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, + 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x15, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x39, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x6f, + 0x6c, 0x6c, 0x65, 0x64, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x50, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, + 0x00, 0x12, 0x52, 0x0a, 0x18, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x68, 0x75, + 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x1a, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1a, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x24, 0x52, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x25, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x00, 0x30, 0x01, 0x12, 0x5b, 0x0a, 0x21, 0x53, 0x65, 0x6e, 0x64, + 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x26, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x73, 0x68, 0x6f, 0x70, 0x2f, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3566,7 +3636,7 @@ func file_proto_orchestrator_proto_rawDescGZIP() []byte { return file_proto_orchestrator_proto_rawDescData } -var file_proto_orchestrator_proto_msgTypes = make([]protoimpl.MessageInfo, 45) +var file_proto_orchestrator_proto_msgTypes = make([]protoimpl.MessageInfo, 46) var file_proto_orchestrator_proto_goTypes = []interface{}{ (*Empty)(nil), // 0: proto.Empty (*ConnectRequest)(nil), // 1: proto.ConnectRequest @@ -3590,29 +3660,30 @@ var file_proto_orchestrator_proto_goTypes = []interface{}{ (*HttpResponse)(nil), // 19: proto.HttpResponse (*GrpcResponse)(nil), // 20: proto.GrpcResponse (*TraceIdResponse)(nil), // 21: proto.TraceIdResponse - (*DataStoreConnectionTestRequest)(nil), // 22: proto.DataStoreConnectionTestRequest - (*DataStoreConnectionTestResponse)(nil), // 23: proto.DataStoreConnectionTestResponse - (*DataStoreConnectionTestSteps)(nil), // 24: proto.DataStoreConnectionTestSteps - (*DataStoreConnectionTestStep)(nil), // 25: proto.DataStoreConnectionTestStep - (*PollingRequest)(nil), // 26: proto.PollingRequest - (*DataStore)(nil), // 27: proto.DataStore - (*JaegerConfig)(nil), // 28: proto.JaegerConfig - (*TempoConfig)(nil), // 29: proto.TempoConfig - (*ElasticConfig)(nil), // 30: proto.ElasticConfig - (*SignalfxConfig)(nil), // 31: proto.SignalfxConfig - (*AwsXRayConfig)(nil), // 32: proto.AwsXRayConfig - (*AzureAppInsightsConfig)(nil), // 33: proto.AzureAppInsightsConfig - (*HttpClientSettings)(nil), // 34: proto.HttpClientSettings - (*GrpcClientSettings)(nil), // 35: proto.GrpcClientSettings - (*TLS)(nil), // 36: proto.TLS - (*TLSSetting)(nil), // 37: proto.TLSSetting - (*PollingResponse)(nil), // 38: proto.PollingResponse - (*Span)(nil), // 39: proto.Span - (*KeyValuePair)(nil), // 40: proto.KeyValuePair - (*KafkaRequest)(nil), // 41: proto.KafkaRequest - (*KafkaAuthentication)(nil), // 42: proto.KafkaAuthentication - (*KafkaPlainAuthentication)(nil), // 43: proto.KafkaPlainAuthentication - (*KafkaResponse)(nil), // 44: proto.KafkaResponse + (*Error)(nil), // 22: proto.Error + (*DataStoreConnectionTestRequest)(nil), // 23: proto.DataStoreConnectionTestRequest + (*DataStoreConnectionTestResponse)(nil), // 24: proto.DataStoreConnectionTestResponse + (*DataStoreConnectionTestSteps)(nil), // 25: proto.DataStoreConnectionTestSteps + (*DataStoreConnectionTestStep)(nil), // 26: proto.DataStoreConnectionTestStep + (*PollingRequest)(nil), // 27: proto.PollingRequest + (*DataStore)(nil), // 28: proto.DataStore + (*JaegerConfig)(nil), // 29: proto.JaegerConfig + (*TempoConfig)(nil), // 30: proto.TempoConfig + (*ElasticConfig)(nil), // 31: proto.ElasticConfig + (*SignalfxConfig)(nil), // 32: proto.SignalfxConfig + (*AwsXRayConfig)(nil), // 33: proto.AwsXRayConfig + (*AzureAppInsightsConfig)(nil), // 34: proto.AzureAppInsightsConfig + (*HttpClientSettings)(nil), // 35: proto.HttpClientSettings + (*GrpcClientSettings)(nil), // 36: proto.GrpcClientSettings + (*TLS)(nil), // 37: proto.TLS + (*TLSSetting)(nil), // 38: proto.TLSSetting + (*PollingResponse)(nil), // 39: proto.PollingResponse + (*Span)(nil), // 40: proto.Span + (*KeyValuePair)(nil), // 41: proto.KeyValuePair + (*KafkaRequest)(nil), // 42: proto.KafkaRequest + (*KafkaAuthentication)(nil), // 43: proto.KafkaAuthentication + (*KafkaPlainAuthentication)(nil), // 44: proto.KafkaPlainAuthentication + (*KafkaResponse)(nil), // 45: proto.KafkaResponse } var file_proto_orchestrator_proto_depIdxs = []int32{ 3, // 0: proto.AgentConfiguration.configuration:type_name -> proto.SessionConfiguration @@ -3621,7 +3692,7 @@ var file_proto_orchestrator_proto_depIdxs = []int32{ 8, // 3: proto.Trigger.http:type_name -> proto.HttpRequest 14, // 4: proto.Trigger.grpc:type_name -> proto.GrpcRequest 16, // 5: proto.Trigger.traceID:type_name -> proto.TraceIDRequest - 41, // 6: proto.Trigger.kafka:type_name -> proto.KafkaRequest + 42, // 6: proto.Trigger.kafka:type_name -> proto.KafkaRequest 9, // 7: proto.HttpRequest.headers:type_name -> proto.HttpHeader 10, // 8: proto.HttpRequest.authentication:type_name -> proto.HttpAuthentication 11, // 9: proto.HttpAuthentication.apiKey:type_name -> proto.ApiKeyAuthentication @@ -3634,63 +3705,65 @@ var file_proto_orchestrator_proto_depIdxs = []int32{ 19, // 16: proto.TriggerResult.http:type_name -> proto.HttpResponse 20, // 17: proto.TriggerResult.grpc:type_name -> proto.GrpcResponse 21, // 18: proto.TriggerResult.traceID:type_name -> proto.TraceIdResponse - 44, // 19: proto.TriggerResult.kafka:type_name -> proto.KafkaResponse - 9, // 20: proto.HttpResponse.headers:type_name -> proto.HttpHeader - 15, // 21: proto.GrpcResponse.metadata:type_name -> proto.GrpcHeader - 27, // 22: proto.DataStoreConnectionTestRequest.datastore:type_name -> proto.DataStore - 5, // 23: proto.DataStoreConnectionTestResponse.agentIdentification:type_name -> proto.AgentIdentification - 24, // 24: proto.DataStoreConnectionTestResponse.steps:type_name -> proto.DataStoreConnectionTestSteps - 25, // 25: proto.DataStoreConnectionTestSteps.portCheck:type_name -> proto.DataStoreConnectionTestStep - 25, // 26: proto.DataStoreConnectionTestSteps.connectivity:type_name -> proto.DataStoreConnectionTestStep - 25, // 27: proto.DataStoreConnectionTestSteps.authentication:type_name -> proto.DataStoreConnectionTestStep - 25, // 28: proto.DataStoreConnectionTestSteps.fetchTraces:type_name -> proto.DataStoreConnectionTestStep - 27, // 29: proto.PollingRequest.datastore:type_name -> proto.DataStore - 28, // 30: proto.DataStore.jaeger:type_name -> proto.JaegerConfig - 29, // 31: proto.DataStore.tempo:type_name -> proto.TempoConfig - 30, // 32: proto.DataStore.opensearch:type_name -> proto.ElasticConfig - 30, // 33: proto.DataStore.elasticapm:type_name -> proto.ElasticConfig - 31, // 34: proto.DataStore.signalfx:type_name -> proto.SignalfxConfig - 32, // 35: proto.DataStore.awsxray:type_name -> proto.AwsXRayConfig - 33, // 36: proto.DataStore.azureappinsights:type_name -> proto.AzureAppInsightsConfig - 35, // 37: proto.JaegerConfig.grpc:type_name -> proto.GrpcClientSettings - 34, // 38: proto.TempoConfig.http:type_name -> proto.HttpClientSettings - 35, // 39: proto.TempoConfig.grpc:type_name -> proto.GrpcClientSettings - 9, // 40: proto.HttpClientSettings.headers:type_name -> proto.HttpHeader - 36, // 41: proto.HttpClientSettings.tls:type_name -> proto.TLS - 10, // 42: proto.HttpClientSettings.authentication:type_name -> proto.HttpAuthentication - 9, // 43: proto.GrpcClientSettings.headers:type_name -> proto.HttpHeader - 36, // 44: proto.GrpcClientSettings.tls:type_name -> proto.TLS - 10, // 45: proto.GrpcClientSettings.auth:type_name -> proto.HttpAuthentication - 37, // 46: proto.TLS.settings:type_name -> proto.TLSSetting - 5, // 47: proto.PollingResponse.agentIdentification:type_name -> proto.AgentIdentification - 39, // 48: proto.PollingResponse.spans:type_name -> proto.Span - 40, // 49: proto.Span.attributes:type_name -> proto.KeyValuePair - 42, // 50: proto.KafkaRequest.authentication:type_name -> proto.KafkaAuthentication - 40, // 51: proto.KafkaRequest.headers:type_name -> proto.KeyValuePair - 43, // 52: proto.KafkaAuthentication.plain:type_name -> proto.KafkaPlainAuthentication - 1, // 53: proto.Orchestrator.Connect:input_type -> proto.ConnectRequest - 5, // 54: proto.Orchestrator.RegisterTriggerAgent:input_type -> proto.AgentIdentification - 17, // 55: proto.Orchestrator.SendTriggerResult:input_type -> proto.TriggerResponse - 5, // 56: proto.Orchestrator.RegisterPollerAgent:input_type -> proto.AgentIdentification - 38, // 57: proto.Orchestrator.SendPolledSpans:input_type -> proto.PollingResponse - 5, // 58: proto.Orchestrator.RegisterShutdownListener:input_type -> proto.AgentIdentification - 5, // 59: proto.Orchestrator.Ping:input_type -> proto.AgentIdentification - 5, // 60: proto.Orchestrator.RegisterDataStoreConnectionTestAgent:input_type -> proto.AgentIdentification - 23, // 61: proto.Orchestrator.SendDataStoreConnectionTestResult:input_type -> proto.DataStoreConnectionTestResponse - 2, // 62: proto.Orchestrator.Connect:output_type -> proto.AgentConfiguration - 6, // 63: proto.Orchestrator.RegisterTriggerAgent:output_type -> proto.TriggerRequest - 0, // 64: proto.Orchestrator.SendTriggerResult:output_type -> proto.Empty - 26, // 65: proto.Orchestrator.RegisterPollerAgent:output_type -> proto.PollingRequest - 0, // 66: proto.Orchestrator.SendPolledSpans:output_type -> proto.Empty - 4, // 67: proto.Orchestrator.RegisterShutdownListener:output_type -> proto.ShutdownRequest - 0, // 68: proto.Orchestrator.Ping:output_type -> proto.Empty - 22, // 69: proto.Orchestrator.RegisterDataStoreConnectionTestAgent:output_type -> proto.DataStoreConnectionTestRequest - 0, // 70: proto.Orchestrator.SendDataStoreConnectionTestResult:output_type -> proto.Empty - 62, // [62:71] is the sub-list for method output_type - 53, // [53:62] is the sub-list for method input_type - 53, // [53:53] is the sub-list for extension type_name - 53, // [53:53] is the sub-list for extension extendee - 0, // [0:53] is the sub-list for field type_name + 45, // 19: proto.TriggerResult.kafka:type_name -> proto.KafkaResponse + 22, // 20: proto.TriggerResult.error:type_name -> proto.Error + 9, // 21: proto.HttpResponse.headers:type_name -> proto.HttpHeader + 15, // 22: proto.GrpcResponse.metadata:type_name -> proto.GrpcHeader + 28, // 23: proto.DataStoreConnectionTestRequest.datastore:type_name -> proto.DataStore + 5, // 24: proto.DataStoreConnectionTestResponse.agentIdentification:type_name -> proto.AgentIdentification + 25, // 25: proto.DataStoreConnectionTestResponse.steps:type_name -> proto.DataStoreConnectionTestSteps + 26, // 26: proto.DataStoreConnectionTestSteps.portCheck:type_name -> proto.DataStoreConnectionTestStep + 26, // 27: proto.DataStoreConnectionTestSteps.connectivity:type_name -> proto.DataStoreConnectionTestStep + 26, // 28: proto.DataStoreConnectionTestSteps.authentication:type_name -> proto.DataStoreConnectionTestStep + 26, // 29: proto.DataStoreConnectionTestSteps.fetchTraces:type_name -> proto.DataStoreConnectionTestStep + 28, // 30: proto.PollingRequest.datastore:type_name -> proto.DataStore + 29, // 31: proto.DataStore.jaeger:type_name -> proto.JaegerConfig + 30, // 32: proto.DataStore.tempo:type_name -> proto.TempoConfig + 31, // 33: proto.DataStore.opensearch:type_name -> proto.ElasticConfig + 31, // 34: proto.DataStore.elasticapm:type_name -> proto.ElasticConfig + 32, // 35: proto.DataStore.signalfx:type_name -> proto.SignalfxConfig + 33, // 36: proto.DataStore.awsxray:type_name -> proto.AwsXRayConfig + 34, // 37: proto.DataStore.azureappinsights:type_name -> proto.AzureAppInsightsConfig + 36, // 38: proto.JaegerConfig.grpc:type_name -> proto.GrpcClientSettings + 35, // 39: proto.TempoConfig.http:type_name -> proto.HttpClientSettings + 36, // 40: proto.TempoConfig.grpc:type_name -> proto.GrpcClientSettings + 9, // 41: proto.HttpClientSettings.headers:type_name -> proto.HttpHeader + 37, // 42: proto.HttpClientSettings.tls:type_name -> proto.TLS + 10, // 43: proto.HttpClientSettings.authentication:type_name -> proto.HttpAuthentication + 9, // 44: proto.GrpcClientSettings.headers:type_name -> proto.HttpHeader + 37, // 45: proto.GrpcClientSettings.tls:type_name -> proto.TLS + 10, // 46: proto.GrpcClientSettings.auth:type_name -> proto.HttpAuthentication + 38, // 47: proto.TLS.settings:type_name -> proto.TLSSetting + 5, // 48: proto.PollingResponse.agentIdentification:type_name -> proto.AgentIdentification + 40, // 49: proto.PollingResponse.spans:type_name -> proto.Span + 22, // 50: proto.PollingResponse.error:type_name -> proto.Error + 41, // 51: proto.Span.attributes:type_name -> proto.KeyValuePair + 43, // 52: proto.KafkaRequest.authentication:type_name -> proto.KafkaAuthentication + 41, // 53: proto.KafkaRequest.headers:type_name -> proto.KeyValuePair + 44, // 54: proto.KafkaAuthentication.plain:type_name -> proto.KafkaPlainAuthentication + 1, // 55: proto.Orchestrator.Connect:input_type -> proto.ConnectRequest + 5, // 56: proto.Orchestrator.RegisterTriggerAgent:input_type -> proto.AgentIdentification + 17, // 57: proto.Orchestrator.SendTriggerResult:input_type -> proto.TriggerResponse + 5, // 58: proto.Orchestrator.RegisterPollerAgent:input_type -> proto.AgentIdentification + 39, // 59: proto.Orchestrator.SendPolledSpans:input_type -> proto.PollingResponse + 5, // 60: proto.Orchestrator.RegisterShutdownListener:input_type -> proto.AgentIdentification + 5, // 61: proto.Orchestrator.Ping:input_type -> proto.AgentIdentification + 5, // 62: proto.Orchestrator.RegisterDataStoreConnectionTestAgent:input_type -> proto.AgentIdentification + 24, // 63: proto.Orchestrator.SendDataStoreConnectionTestResult:input_type -> proto.DataStoreConnectionTestResponse + 2, // 64: proto.Orchestrator.Connect:output_type -> proto.AgentConfiguration + 6, // 65: proto.Orchestrator.RegisterTriggerAgent:output_type -> proto.TriggerRequest + 0, // 66: proto.Orchestrator.SendTriggerResult:output_type -> proto.Empty + 27, // 67: proto.Orchestrator.RegisterPollerAgent:output_type -> proto.PollingRequest + 0, // 68: proto.Orchestrator.SendPolledSpans:output_type -> proto.Empty + 4, // 69: proto.Orchestrator.RegisterShutdownListener:output_type -> proto.ShutdownRequest + 0, // 70: proto.Orchestrator.Ping:output_type -> proto.Empty + 23, // 71: proto.Orchestrator.RegisterDataStoreConnectionTestAgent:output_type -> proto.DataStoreConnectionTestRequest + 0, // 72: proto.Orchestrator.SendDataStoreConnectionTestResult:output_type -> proto.Empty + 64, // [64:73] is the sub-list for method output_type + 55, // [55:64] is the sub-list for method input_type + 55, // [55:55] is the sub-list for extension type_name + 55, // [55:55] is the sub-list for extension extendee + 0, // [0:55] is the sub-list for field type_name } func init() { file_proto_orchestrator_proto_init() } @@ -3964,7 +4037,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DataStoreConnectionTestRequest); i { + switch v := v.(*Error); i { case 0: return &v.state case 1: @@ -3976,7 +4049,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DataStoreConnectionTestResponse); i { + switch v := v.(*DataStoreConnectionTestRequest); i { case 0: return &v.state case 1: @@ -3988,7 +4061,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DataStoreConnectionTestSteps); i { + switch v := v.(*DataStoreConnectionTestResponse); i { case 0: return &v.state case 1: @@ -4000,7 +4073,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DataStoreConnectionTestStep); i { + switch v := v.(*DataStoreConnectionTestSteps); i { case 0: return &v.state case 1: @@ -4012,7 +4085,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PollingRequest); i { + switch v := v.(*DataStoreConnectionTestStep); i { case 0: return &v.state case 1: @@ -4024,7 +4097,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DataStore); i { + switch v := v.(*PollingRequest); i { case 0: return &v.state case 1: @@ -4036,7 +4109,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*JaegerConfig); i { + switch v := v.(*DataStore); i { case 0: return &v.state case 1: @@ -4048,7 +4121,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TempoConfig); i { + switch v := v.(*JaegerConfig); i { case 0: return &v.state case 1: @@ -4060,7 +4133,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ElasticConfig); i { + switch v := v.(*TempoConfig); i { case 0: return &v.state case 1: @@ -4072,7 +4145,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SignalfxConfig); i { + switch v := v.(*ElasticConfig); i { case 0: return &v.state case 1: @@ -4084,7 +4157,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AwsXRayConfig); i { + switch v := v.(*SignalfxConfig); i { case 0: return &v.state case 1: @@ -4096,7 +4169,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AzureAppInsightsConfig); i { + switch v := v.(*AwsXRayConfig); i { case 0: return &v.state case 1: @@ -4108,7 +4181,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HttpClientSettings); i { + switch v := v.(*AzureAppInsightsConfig); i { case 0: return &v.state case 1: @@ -4120,7 +4193,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GrpcClientSettings); i { + switch v := v.(*HttpClientSettings); i { case 0: return &v.state case 1: @@ -4132,7 +4205,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TLS); i { + switch v := v.(*GrpcClientSettings); i { case 0: return &v.state case 1: @@ -4144,7 +4217,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TLSSetting); i { + switch v := v.(*TLS); i { case 0: return &v.state case 1: @@ -4156,7 +4229,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PollingResponse); i { + switch v := v.(*TLSSetting); i { case 0: return &v.state case 1: @@ -4168,7 +4241,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Span); i { + switch v := v.(*PollingResponse); i { case 0: return &v.state case 1: @@ -4180,7 +4253,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KeyValuePair); i { + switch v := v.(*Span); i { case 0: return &v.state case 1: @@ -4192,7 +4265,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KafkaRequest); i { + switch v := v.(*KeyValuePair); i { case 0: return &v.state case 1: @@ -4204,7 +4277,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KafkaAuthentication); i { + switch v := v.(*KafkaRequest); i { case 0: return &v.state case 1: @@ -4216,7 +4289,7 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KafkaPlainAuthentication); i { + switch v := v.(*KafkaAuthentication); i { case 0: return &v.state case 1: @@ -4228,6 +4301,18 @@ func file_proto_orchestrator_proto_init() { } } file_proto_orchestrator_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KafkaPlainAuthentication); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_orchestrator_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*KafkaResponse); i { case 0: return &v.state @@ -4246,7 +4331,7 @@ func file_proto_orchestrator_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_orchestrator_proto_rawDesc, NumEnums: 0, - NumMessages: 45, + NumMessages: 46, NumExtensions: 0, NumServices: 1, }, diff --git a/agent/proto/orchestrator.proto b/agent/proto/orchestrator.proto index 7c5422e8fd..cab8f8b7cc 100644 --- a/agent/proto/orchestrator.proto +++ b/agent/proto/orchestrator.proto @@ -157,6 +157,7 @@ message TriggerResult { GrpcResponse grpc = 3; TraceIdResponse traceID = 4; KafkaResponse kafka = 5; + Error error = 6; } message HttpResponse { @@ -176,6 +177,10 @@ message TraceIdResponse { string id = 1; } +message Error { + string message = 1; +} + message DataStoreConnectionTestRequest { string requestID = 1; DataStore datastore = 2; @@ -302,6 +307,7 @@ message PollingResponse { string traceID = 5; repeated Span spans = 6; bool traceFound = 7; + Error error = 8; } message Span { diff --git a/agent/workers/poller.go b/agent/workers/poller.go index 769825630b..9d1fc1eb68 100644 --- a/agent/workers/poller.go +++ b/agent/workers/poller.go @@ -50,6 +50,29 @@ func NewPollerWorker(client *client.Client, opts ...PollerOption) *PollerWorker } func (w *PollerWorker) Poll(ctx context.Context, request *proto.PollingRequest) error { + err := w.poll(ctx, request) + if err != nil { + sendErr := w.client.SendTrace(ctx, &proto.PollingResponse{ + RequestID: request.RequestID, + AgentIdentification: w.client.SessionConfiguration().AgentIdentification, + TestID: request.GetTestID(), + RunID: request.GetRunID(), + TraceID: request.TraceID, + TraceFound: false, + Error: &proto.Error{ + Message: err.Error(), + }, + }) + + if sendErr != nil { + return fmt.Errorf("could not report polling error back to the server: %w. Original error: %s", sendErr, err.Error()) + } + } + + return err +} + +func (w *PollerWorker) poll(ctx context.Context, request *proto.PollingRequest) error { datastoreConfig, err := convertProtoToDataStore(request.Datastore) if err != nil { return err diff --git a/agent/workers/poller_test.go b/agent/workers/poller_test.go index 97b6d13d91..b63b287e5c 100644 --- a/agent/workers/poller_test.go +++ b/agent/workers/poller_test.go @@ -177,3 +177,44 @@ func TestPollerWorkerWithInmemoryDatastore(t *testing.T) { assert.True(t, pollingResponse.TraceFound) assert.Len(t, pollingResponse.Spans, 2) } + +func TestPollerWithInvalidDataStore(t *testing.T) { + ctx := context.Background() + controlPlane := mocks.NewGrpcServer() + + client, err := client.Connect(ctx, controlPlane.Addr()) + require.NoError(t, err) + + pollerWorker := workers.NewPollerWorker(client) + + client.OnPollingRequest(func(ctx context.Context, pr *proto.PollingRequest) error { + return pollerWorker.Poll(ctx, pr) + }) + + err = client.Start(ctx) + require.NoError(t, err) + + pollingRequest := proto.PollingRequest{ + TestID: "test", + RunID: 1, + TraceID: "42a2c381da1a5b3a32bc4988bf2431b0", + Datastore: &proto.DataStore{ + Type: "tempo", + Tempo: &proto.TempoConfig{ + Type: "http", + Http: &proto.HttpClientSettings{ + Url: "http://localhost:16686", // invalid jaeger port, this should cause an error + }, + }, + }, + } + + controlPlane.SendPollingRequest(&pollingRequest) + + time.Sleep(1 * time.Second) + + pollingResponse := controlPlane.GetLastPollingResponse() + require.NotNil(t, pollingResponse, "agent did not send polling response back to server") + assert.NotNil(t, pollingResponse.Error) + assert.Contains(t, pollingResponse.Error.Message, "connection refused") +} diff --git a/agent/workers/trigger.go b/agent/workers/trigger.go index 9f2f328ce1..add27f0341 100644 --- a/agent/workers/trigger.go +++ b/agent/workers/trigger.go @@ -51,6 +51,29 @@ func NewTriggerWorker(client *client.Client, opts ...TriggerOption) *TriggerWork } func (w *TriggerWorker) Trigger(ctx context.Context, triggerRequest *proto.TriggerRequest) error { + err := w.trigger(ctx, triggerRequest) + if err != nil { + sendErr := w.client.SendTriggerResponse(ctx, &proto.TriggerResponse{ + RequestID: triggerRequest.RequestID, + AgentIdentification: w.client.SessionConfiguration().AgentIdentification, + TestID: triggerRequest.GetTestID(), + RunID: triggerRequest.GetRunID(), + TriggerResult: &proto.TriggerResult{ + Error: &proto.Error{ + Message: err.Error(), + }, + }, + }) + + if sendErr != nil { + return fmt.Errorf("could not report trigger error back to the server: %w. Original error: %s", sendErr, err.Error()) + } + } + + return err +} + +func (w *TriggerWorker) trigger(ctx context.Context, triggerRequest *proto.TriggerRequest) error { triggerConfig := convertProtoToTrigger(triggerRequest.Trigger) triggerer, err := w.registry.Get(triggerConfig.Type) if err != nil { diff --git a/agent/workers/trigger_test.go b/agent/workers/trigger_test.go index 308bad93c9..d1475ea863 100644 --- a/agent/workers/trigger_test.go +++ b/agent/workers/trigger_test.go @@ -113,6 +113,51 @@ func TestTriggerAgainstGoogle(t *testing.T) { assert.Equal(t, int32(http.StatusOK), response.TriggerResult.Http.StatusCode) } +func TestTriggerInexistentAPI(t *testing.T) { + cache := collector.NewTraceCache() + controlPlane := mocks.NewGrpcServer() + + client, err := client.Connect(context.Background(), controlPlane.Addr()) + require.NoError(t, err) + + triggerWorker := workers.NewTriggerWorker(client, workers.WithTraceCache(cache)) + + client.OnTriggerRequest(func(ctx context.Context, tr *proto.TriggerRequest) error { + err := triggerWorker.Trigger(ctx, tr) + return err + }) + + client.Start(context.Background()) + + traceID := "42a2c381da1a5b3a32bc4988bf2431b0" + + triggerRequest := &proto.TriggerRequest{ + TestID: "my test", + RunID: 1, + TraceID: traceID, + Trigger: &proto.Trigger{ + Type: "http", + Http: &proto.HttpRequest{ + Method: "GET", + Url: "https://localhost:32148", // hopefully no one uses this port + Headers: []*proto.HttpHeader{ + {Key: "Content-Type", Value: "application/json"}, + }, + }, + }, + } + + // make the control plane send a trigger request to the agent + controlPlane.SendTriggerRequest(triggerRequest) + time.Sleep(1 * time.Second) + + response := controlPlane.GetLastTriggerResponse() + + require.NotNil(t, response) + assert.NotNil(t, response.TriggerResult.Error) + assert.Contains(t, response.TriggerResult.Error.Message, "connection refused") +} + func createHelloWorldApi() *httptest.Server { return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte(`{"hello": "world"}`)) From d2ec14f8ff632d27d8b8867e29770466b0a8cff1 Mon Sep 17 00:00:00 2001 From: Matheus Nogueira Date: Fri, 3 Nov 2023 15:18:36 -0300 Subject: [PATCH 09/19] feat: date generator functions (#3327) * feat(server): support generator functions with optional parameters * feat(server): support date and datetime generator functions * docs: add `date` and `dateTime` functions to the list * Update docs/docs/cli/creating-tests.mdx Co-authored-by: Julianne Fermi * Update docs/docs/cli/creating-tests.mdx Co-authored-by: Julianne Fermi * Update docs/docs/cli/creating-tests.mdx Co-authored-by: Julianne Fermi * Update docs/docs/cli/creating-tests.mdx Co-authored-by: Julianne Fermi --------- Co-authored-by: Julianne Fermi --- docs/docs/cli/creating-tests.mdx | 30 ++++--- go.mod | 1 + go.sum | 2 + server/expression/executor_test.go | 21 +++++ server/expression/functions/function.go | 82 ++++++++++++++----- .../expression/functions/function_registry.go | 21 +++-- .../functions/function_registry_test.go | 16 +++- server/expression/functions/functions.go | 19 +++++ 8 files changed, 152 insertions(+), 40 deletions(-) diff --git a/docs/docs/cli/creating-tests.mdx b/docs/docs/cli/creating-tests.mdx index fc07fe87c0..5752a04e04 100644 --- a/docs/docs/cli/creating-tests.mdx +++ b/docs/docs/cli/creating-tests.mdx @@ -169,20 +169,26 @@ Generator functions can be invoked as part of expressions. Therefore, you only n Available functions: | Function | Description | -| :-------------------- | ------------------------------------------------------------------------------------- | -| `uuid()` | Generates a random v4 uuid. | -| `firstName()` | Generates a random English first name. | -| `lastName()` | Generates a random English last name. | -| `fullName()` | Generates a random English first and last name. | -| `email()` | Generates a random email address. | -| `phone()` | Generates a random phone number. | -| `creditCard()` | Generates a random credit card number (from 12 to 19 digits). | -| `creditCardCvv()` | Generates a random credit card cvv (3 digits). | -| `creditCardExpDate()` | Generates a random credit card expiration date (mm/yy). | -| `randomInt(min, max)` | Generates a random integer contained in the closed interval defined by [`min`, `max`]. | +| :-------------------- | --------------------------------------------------------------------------------------------- | +| `uuid()` | Generates a random v4 uuid. | +| `firstName()` | Generates a random English first name. | +| `lastName()` | Generates a random English last name. | +| `fullName()` | Generates a random English first and last name. | +| `email()` | Generates a random email address. | +| `phone()` | Generates a random phone number. | +| `creditCard()` | Generates a random credit card number (from 12 to 19 digits). | +| `creditCardCvv()` | Generates a random credit card cvv (3 digits). | +| `creditCardExpDate()` | Generates a random credit card expiration date (mm/yy). | +| `randomInt(min, max)` | Generates a random integer contained in the closed interval defined by [`min`, `max`]. | +| `date(format?)` | Get the current date and formats it. Default is `YYYY-MM-DD` but you can specify other formats.| +| `dateTime(format?)` | Get the current datetime and formats it. Default is RFC3339 but you can specify other formats.| :::tip -[Continue reading about Test Specs, here.](/cli/creating-test-specifications) +[Continue reading about date and datetime formats here.](https://www.w3.org/TR/NOTE-datetime) +::: + +:::tip +[Continue reading about Test Specs here.](/cli/creating-test-specifications) ::: :::tip diff --git a/go.mod b/go.mod index 25a3407036..7bcc123dc7 100644 --- a/go.mod +++ b/go.mod @@ -173,6 +173,7 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + gitlab.com/metakeule/fmtdate v1.2.2 // indirect go.opentelemetry.io/collector v0.80.0 // indirect go.opentelemetry.io/collector/config/configauth v0.80.0 // indirect go.opentelemetry.io/collector/config/confignet v0.80.0 // indirect diff --git a/go.sum b/go.sum index 44dbc22507..8d74694863 100644 --- a/go.sum +++ b/go.sum @@ -1851,6 +1851,8 @@ github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +gitlab.com/metakeule/fmtdate v1.2.2 h1:ce0Qnwo6PAONi6xwPr4YxdxAFIKqNfoMbHG4c49vIjk= +gitlab.com/metakeule/fmtdate v1.2.2/go.mod h1:uZUf21xepWGLp6PgJGBbHeBVWO+/gsKi3Gdh0Fu4lGg= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= diff --git a/server/expression/executor_test.go b/server/expression/executor_test.go index b333d00f1b..b66db13777 100644 --- a/server/expression/executor_test.go +++ b/server/expression/executor_test.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" "testing" + "time" "github.com/kubeshop/tracetest/server/expression" "github.com/kubeshop/tracetest/server/traces" @@ -244,6 +245,26 @@ func TestFunctionExecution(t *testing.T) { Query: `randomInt(10,20) < 10`, ShouldPass: false, }, + { + Name: "should_generate_date_string", + Query: fmt.Sprintf(`date() = "%s"`, time.Now().Format(time.DateOnly)), + ShouldPass: true, + }, + { + Name: "should_generate_date_string", + Query: fmt.Sprintf(`date("DD/MM/YYYY") = "%s"`, time.Now().Format("02/01/2006")), + ShouldPass: true, + }, + { + Name: "should_generate_date_string", + Query: fmt.Sprintf(`dateTime() = "%s"`, time.Now().Format(time.RFC3339)), + ShouldPass: true, + }, + { + Name: "should_generate_date_string", + Query: fmt.Sprintf(`dateTime("DD/MM/YYYY hh:mm") = "%s"`, time.Now().Format("02/01/2006 15:04")), + ShouldPass: true, + }, } executeTestCases(t, testCases) diff --git a/server/expression/functions/function.go b/server/expression/functions/function.go index 66f4c80b6e..d5ca4a9363 100644 --- a/server/expression/functions/function.go +++ b/server/expression/functions/function.go @@ -9,20 +9,55 @@ import ( type Invoker func(args ...types.TypedValue) string type Function struct { - name string - invoker Invoker - argTypes []types.Type + name string + invoker Invoker + parameters []Parameter +} + +func (f Function) NumRequiredParams() int { + count := 0 + for _, param := range f.parameters { + if !param.optional { + count++ + } + } + + return count +} + +func (f Function) Validate() error { + foundOptionalParameterIndex := -1 + for i, param := range f.parameters { + if param.optional { + foundOptionalParameterIndex = i + } + + if foundOptionalParameterIndex > -1 && !param.optional { + // there's a required parameter after a optional parameter + // this is invalid in most programming languages and makes it + // extremely hard to resolve the function, so fail it. + return fmt.Errorf("argument at index %d is required, but it's after optional argument at index %d", i, foundOptionalParameterIndex) + } + } + + return nil +} + +type Parameter struct { + pType types.Type + optional bool } func (f Function) Invoke(args ...types.TypedValue) (types.TypedValue, error) { - if len(args) != len(f.argTypes) { - return types.TypedValue{}, fmt.Errorf("invalid number of arguments. Expected %d, got %d", len(f.argTypes), len(args)) + numberRequiredParams := f.NumRequiredParams() + if len(args) < numberRequiredParams { + return types.TypedValue{}, fmt.Errorf("missing required parameters. Expected at least %d params, got %d", numberRequiredParams, len(args)) } for i, arg := range args { - expectedArgType := f.argTypes[i] - if arg.Type != expectedArgType { - return types.TypedValue{}, fmt.Errorf("invalid argument type on index %d: expected %s, got %s", i, arg.Type.String(), expectedArgType.String()) + param := f.parameters[i] + if arg.Type != param.pType { + return types.TypedValue{}, fmt.Errorf("invalid argument type on index %d: expected %s, got %s", i, arg.Type.String(), param.pType.String()) } } @@ -31,19 +66,28 @@ func (f Function) Invoke(args ...types.TypedValue) (types.TypedValue, error) { } func DefaultRegistry() Registry { - emptyArgsConfig := []types.Type{} registry := newRegistry() - registry.Add("uuid", generateUUID, emptyArgsConfig) - registry.Add("firstName", generateFirstName, emptyArgsConfig) - registry.Add("lastName", generateLastName, emptyArgsConfig) - registry.Add("fullName", generateFullName, emptyArgsConfig) - registry.Add("email", generateEmail, emptyArgsConfig) - registry.Add("phone", generatePhoneNumber, emptyArgsConfig) - registry.Add("creditCard", generateCreditCard, emptyArgsConfig) - registry.Add("creditCardCvv", generateCreditCardCVV, emptyArgsConfig) - registry.Add("creditCardExpDate", generateCreditCardExpiration, emptyArgsConfig) - registry.Add("randomInt", generateRandomInt, []types.Type{types.TypeNumber, types.TypeNumber}) + registry.Add("uuid", generateUUID) + registry.Add("firstName", generateFirstName) + registry.Add("lastName", generateLastName) + registry.Add("fullName", generateFullName) + registry.Add("email", generateEmail) + registry.Add("phone", generatePhoneNumber) + registry.Add("date", generateDate, OptionalParam(types.TypeString)) + registry.Add("dateTime", generateDateTime, OptionalParam(types.TypeString)) + registry.Add("creditCard", generateCreditCard) + registry.Add("creditCardCvv", generateCreditCardCVV) + registry.Add("creditCardExpDate", generateCreditCardExpiration) + registry.Add("randomInt", generateRandomInt, Param(types.TypeNumber), Param(types.TypeNumber)) return registry } + +func Param(pType types.Type) Parameter { + return Parameter{pType: pType, optional: false} +} + +func OptionalParam(pType types.Type) Parameter { + return Parameter{pType: pType, optional: true} +} diff --git a/server/expression/functions/function_registry.go b/server/expression/functions/function_registry.go index b2d0378566..fc34dd9323 100644 --- a/server/expression/functions/function_registry.go +++ b/server/expression/functions/function_registry.go @@ -3,12 +3,10 @@ package functions import ( "fmt" "sync" - - "github.com/kubeshop/tracetest/server/expression/types" ) type Registry interface { - Add(string, Invoker, []types.Type) + Add(string, Invoker, ...Parameter) Get(string) (Function, error) } @@ -23,15 +21,22 @@ type registry struct { mutex sync.Mutex } -func (r *registry) Add(name string, function Invoker, argsConfig []types.Type) { +func (r *registry) Add(name string, function Invoker, argsConfig ...Parameter) { r.mutex.Lock() defer r.mutex.Unlock() - r.functions[name] = Function{ - name: name, - invoker: function, - argTypes: argsConfig, + f := Function{ + name: name, + invoker: function, + parameters: argsConfig, + } + + if err := f.Validate(); err != nil { + // this is a development error. Fail it as fast as possible + panic(err) } + + r.functions[name] = f } func (r *registry) Get(name string) (Function, error) { diff --git a/server/expression/functions/function_registry_test.go b/server/expression/functions/function_registry_test.go index 6734be8961..7fea2a73c1 100644 --- a/server/expression/functions/function_registry_test.go +++ b/server/expression/functions/function_registry_test.go @@ -10,6 +10,20 @@ import ( "github.com/stretchr/testify/require" ) +func TestFunctionValidation(t *testing.T) { + registry := functions.DefaultRegistry() + + emptyStringFn := func(args ...types.TypedValue) string { return "" } + + assert.Panics(t, func() { + registry.Add("faulty", emptyStringFn, + functions.Param(types.TypeString), + functions.OptionalParam(types.TypeString), + functions.Param(types.TypeNumber), + ) + }) +} + func TestFunctionWithoutArgs(t *testing.T) { registry := functions.DefaultRegistry() @@ -55,7 +69,7 @@ func TestFunctionWithWrongArgNumber(t *testing.T) { _, err = function.Invoke() assert.Error(t, err) - assert.Contains(t, err.Error(), "invalid number of arguments") + assert.Contains(t, err.Error(), "missing required parameters") } func TestFunctionWithWrongArgType(t *testing.T) { diff --git a/server/expression/functions/functions.go b/server/expression/functions/functions.go index b5530fa4cb..42d5895fc1 100644 --- a/server/expression/functions/functions.go +++ b/server/expression/functions/functions.go @@ -3,9 +3,11 @@ package functions import ( "fmt" "strconv" + "time" "github.com/brianvoe/gofakeit/v6" "github.com/kubeshop/tracetest/server/expression/types" + "gitlab.com/metakeule/fmtdate" ) func generateUUID(args ...types.TypedValue) string { @@ -50,3 +52,20 @@ func generateRandomInt(args ...types.TypedValue) string { max, _ := strconv.Atoi(args[1].Value) return fmt.Sprintf("%d", gofakeit.Number(min, max)) } + +func generateDate(args ...types.TypedValue) string { + format := time.DateOnly + if len(args) > 0 { + format = args[0].Value + } + + return fmtdate.Format(format, time.Now()) +} + +func generateDateTime(args ...types.TypedValue) string { + format := time.RFC3339 + if len(args) > 0 { + format = args[0].Value + } + return fmtdate.Format(format, time.Now()) +} From 6bb9e6384a3b39008689a447e40d660300d0e847 Mon Sep 17 00:00:00 2001 From: Matheus Nogueira Date: Fri, 3 Nov 2023 19:27:13 -0300 Subject: [PATCH 10/19] feat: accept trigger error and run state from endpoint (#3335) --- api/triggers.yaml | 14 ++ cli/openapi/model_trigger_error.go | 232 ++++++++++++++++++ .../model_trigger_result_trigger_result.go | 36 +++ server/http/controller.go | 1 + server/http/mappings/tests.go | 28 +++ server/openapi/model_trigger_error.go | 37 +++ .../model_trigger_result_trigger_result.go | 5 + web/src/types/Generated.types.ts | 7 + 8 files changed, 360 insertions(+) create mode 100644 cli/openapi/model_trigger_error.go create mode 100644 server/openapi/model_trigger_error.go diff --git a/api/triggers.yaml b/api/triggers.yaml index 8e1b70cf1d..dc9192d46a 100644 --- a/api/triggers.yaml +++ b/api/triggers.yaml @@ -33,3 +33,17 @@ components: $ref: "./traceid.yaml#/components/schemas/TRACEIDResponse" kafka: $ref: "./kafka.yaml#/components/schemas/KafkaResponse" + error: + $ref: "#/components/schemas/TriggerError" + + TriggerError: + type: object + properties: + connectionError: + type: boolean + runningOnContainer: + type: boolean + targetsLocalhost: + type: boolean + message: + type: string diff --git a/cli/openapi/model_trigger_error.go b/cli/openapi/model_trigger_error.go new file mode 100644 index 0000000000..d4e0d1f280 --- /dev/null +++ b/cli/openapi/model_trigger_error.go @@ -0,0 +1,232 @@ +/* +TraceTest + +OpenAPI definition for TraceTest endpoint and resources + +API version: 0.2.1 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the TriggerError type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &TriggerError{} + +// TriggerError struct for TriggerError +type TriggerError struct { + ConnectionError *bool `json:"connectionError,omitempty"` + RunningOnContainer *bool `json:"runningOnContainer,omitempty"` + TargetsLocalhost *bool `json:"targetsLocalhost,omitempty"` + Message *string `json:"message,omitempty"` +} + +// NewTriggerError instantiates a new TriggerError object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewTriggerError() *TriggerError { + this := TriggerError{} + return &this +} + +// NewTriggerErrorWithDefaults instantiates a new TriggerError object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewTriggerErrorWithDefaults() *TriggerError { + this := TriggerError{} + return &this +} + +// GetConnectionError returns the ConnectionError field value if set, zero value otherwise. +func (o *TriggerError) GetConnectionError() bool { + if o == nil || isNil(o.ConnectionError) { + var ret bool + return ret + } + return *o.ConnectionError +} + +// GetConnectionErrorOk returns a tuple with the ConnectionError field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *TriggerError) GetConnectionErrorOk() (*bool, bool) { + if o == nil || isNil(o.ConnectionError) { + return nil, false + } + return o.ConnectionError, true +} + +// HasConnectionError returns a boolean if a field has been set. +func (o *TriggerError) HasConnectionError() bool { + if o != nil && !isNil(o.ConnectionError) { + return true + } + + return false +} + +// SetConnectionError gets a reference to the given bool and assigns it to the ConnectionError field. +func (o *TriggerError) SetConnectionError(v bool) { + o.ConnectionError = &v +} + +// GetRunningOnContainer returns the RunningOnContainer field value if set, zero value otherwise. +func (o *TriggerError) GetRunningOnContainer() bool { + if o == nil || isNil(o.RunningOnContainer) { + var ret bool + return ret + } + return *o.RunningOnContainer +} + +// GetRunningOnContainerOk returns a tuple with the RunningOnContainer field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *TriggerError) GetRunningOnContainerOk() (*bool, bool) { + if o == nil || isNil(o.RunningOnContainer) { + return nil, false + } + return o.RunningOnContainer, true +} + +// HasRunningOnContainer returns a boolean if a field has been set. +func (o *TriggerError) HasRunningOnContainer() bool { + if o != nil && !isNil(o.RunningOnContainer) { + return true + } + + return false +} + +// SetRunningOnContainer gets a reference to the given bool and assigns it to the RunningOnContainer field. +func (o *TriggerError) SetRunningOnContainer(v bool) { + o.RunningOnContainer = &v +} + +// GetTargetsLocalhost returns the TargetsLocalhost field value if set, zero value otherwise. +func (o *TriggerError) GetTargetsLocalhost() bool { + if o == nil || isNil(o.TargetsLocalhost) { + var ret bool + return ret + } + return *o.TargetsLocalhost +} + +// GetTargetsLocalhostOk returns a tuple with the TargetsLocalhost field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *TriggerError) GetTargetsLocalhostOk() (*bool, bool) { + if o == nil || isNil(o.TargetsLocalhost) { + return nil, false + } + return o.TargetsLocalhost, true +} + +// HasTargetsLocalhost returns a boolean if a field has been set. +func (o *TriggerError) HasTargetsLocalhost() bool { + if o != nil && !isNil(o.TargetsLocalhost) { + return true + } + + return false +} + +// SetTargetsLocalhost gets a reference to the given bool and assigns it to the TargetsLocalhost field. +func (o *TriggerError) SetTargetsLocalhost(v bool) { + o.TargetsLocalhost = &v +} + +// GetMessage returns the Message field value if set, zero value otherwise. +func (o *TriggerError) GetMessage() string { + if o == nil || isNil(o.Message) { + var ret string + return ret + } + return *o.Message +} + +// GetMessageOk returns a tuple with the Message field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *TriggerError) GetMessageOk() (*string, bool) { + if o == nil || isNil(o.Message) { + return nil, false + } + return o.Message, true +} + +// HasMessage returns a boolean if a field has been set. +func (o *TriggerError) HasMessage() bool { + if o != nil && !isNil(o.Message) { + return true + } + + return false +} + +// SetMessage gets a reference to the given string and assigns it to the Message field. +func (o *TriggerError) SetMessage(v string) { + o.Message = &v +} + +func (o TriggerError) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o TriggerError) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !isNil(o.ConnectionError) { + toSerialize["connectionError"] = o.ConnectionError + } + if !isNil(o.RunningOnContainer) { + toSerialize["runningOnContainer"] = o.RunningOnContainer + } + if !isNil(o.TargetsLocalhost) { + toSerialize["targetsLocalhost"] = o.TargetsLocalhost + } + if !isNil(o.Message) { + toSerialize["message"] = o.Message + } + return toSerialize, nil +} + +type NullableTriggerError struct { + value *TriggerError + isSet bool +} + +func (v NullableTriggerError) Get() *TriggerError { + return v.value +} + +func (v *NullableTriggerError) Set(val *TriggerError) { + v.value = val + v.isSet = true +} + +func (v NullableTriggerError) IsSet() bool { + return v.isSet +} + +func (v *NullableTriggerError) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableTriggerError(val *TriggerError) *NullableTriggerError { + return &NullableTriggerError{value: val, isSet: true} +} + +func (v NullableTriggerError) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableTriggerError) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/cli/openapi/model_trigger_result_trigger_result.go b/cli/openapi/model_trigger_result_trigger_result.go index 918571c28b..371cb335e9 100644 --- a/cli/openapi/model_trigger_result_trigger_result.go +++ b/cli/openapi/model_trigger_result_trigger_result.go @@ -23,6 +23,7 @@ type TriggerResultTriggerResult struct { Grpc *GRPCResponse `json:"grpc,omitempty"` Traceid *TRACEIDResponse `json:"traceid,omitempty"` Kafka *KafkaResponse `json:"kafka,omitempty"` + Error *TriggerError `json:"error,omitempty"` } // NewTriggerResultTriggerResult instantiates a new TriggerResultTriggerResult object @@ -170,6 +171,38 @@ func (o *TriggerResultTriggerResult) SetKafka(v KafkaResponse) { o.Kafka = &v } +// GetError returns the Error field value if set, zero value otherwise. +func (o *TriggerResultTriggerResult) GetError() TriggerError { + if o == nil || isNil(o.Error) { + var ret TriggerError + return ret + } + return *o.Error +} + +// GetErrorOk returns a tuple with the Error field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *TriggerResultTriggerResult) GetErrorOk() (*TriggerError, bool) { + if o == nil || isNil(o.Error) { + return nil, false + } + return o.Error, true +} + +// HasError returns a boolean if a field has been set. +func (o *TriggerResultTriggerResult) HasError() bool { + if o != nil && !isNil(o.Error) { + return true + } + + return false +} + +// SetError gets a reference to the given TriggerError and assigns it to the Error field. +func (o *TriggerResultTriggerResult) SetError(v TriggerError) { + o.Error = &v +} + func (o TriggerResultTriggerResult) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -192,6 +225,9 @@ func (o TriggerResultTriggerResult) ToMap() (map[string]interface{}, error) { if !isNil(o.Kafka) { toSerialize["kafka"] = o.Kafka } + if !isNil(o.Error) { + toSerialize["error"] = o.Error + } return toSerialize, nil } diff --git a/server/http/controller.go b/server/http/controller.go index d0c40d12a3..f66505bc2c 100644 --- a/server/http/controller.go +++ b/server/http/controller.go @@ -735,6 +735,7 @@ func (c *controller) UpdateTestRun(ctx context.Context, testID string, runID int // Prevents bad data in other fields to override correct data existingRun.TriggerResult = run.TriggerResult existingRun.Trace = traces.MergeTraces(existingRun.Trace, run.Trace) + existingRun.State = run.State err = c.testRunRepository.UpdateRun(ctx, existingRun) if err != nil { diff --git a/server/http/mappings/tests.go b/server/http/mappings/tests.go index 9d769e7340..caf88ae9cd 100644 --- a/server/http/mappings/tests.go +++ b/server/http/mappings/tests.go @@ -128,10 +128,24 @@ func (m OpenAPI) TriggerResult(in trigger.TriggerResult) openapi.TriggerResult { Grpc: m.GRPCResponse(in.GRPC), Traceid: m.TraceIDResponse(in.TraceID), Kafka: m.KafkaResponse(in.Kafka), + Error: m.TriggerError(in.Error), }, } } +func (m OpenAPI) TriggerError(in *trigger.TriggerError) openapi.TriggerError { + if in == nil { + return openapi.TriggerError{} + } + + return openapi.TriggerError{ + ConnectionError: in.ConnectionError, + RunningOnContainer: in.RunningOnContainer, + TargetsLocalhost: in.TargetsLocalhost, + Message: in.ErrorMessage, + } +} + func (m OpenAPI) Tests(in []test.Test) []openapi.Test { tests := make([]openapi.Test, len(in)) for i, t := range in { @@ -451,6 +465,20 @@ func (m Model) TriggerResult(in openapi.TriggerResult) trigger.TriggerResult { HTTP: m.HTTPResponse(in.TriggerResult.Http), GRPC: m.GRPCResponse(in.TriggerResult.Grpc), TraceID: m.TraceIDResponse(in.TriggerResult.Traceid), + Error: m.TriggerError(in.TriggerResult.Error), + } +} + +func (m Model) TriggerError(in openapi.TriggerError) *trigger.TriggerError { + if in.Message == "" { + return nil + } + + return &trigger.TriggerError{ + ConnectionError: in.ConnectionError, + RunningOnContainer: in.RunningOnContainer, + TargetsLocalhost: in.TargetsLocalhost, + ErrorMessage: in.Message, } } diff --git a/server/openapi/model_trigger_error.go b/server/openapi/model_trigger_error.go new file mode 100644 index 0000000000..830e3b74b7 --- /dev/null +++ b/server/openapi/model_trigger_error.go @@ -0,0 +1,37 @@ +/* + * TraceTest + * + * OpenAPI definition for TraceTest endpoint and resources + * + * API version: 0.2.1 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +type TriggerError struct { + ConnectionError bool `json:"connectionError,omitempty"` + + RunningOnContainer bool `json:"runningOnContainer,omitempty"` + + TargetsLocalhost bool `json:"targetsLocalhost,omitempty"` + + Message string `json:"message,omitempty"` +} + +// AssertTriggerErrorRequired checks if the required fields are not zero-ed +func AssertTriggerErrorRequired(obj TriggerError) error { + return nil +} + +// AssertRecurseTriggerErrorRequired recursively checks if required fields are not zero-ed in a nested slice. +// Accepts only nested slice of TriggerError (e.g. [][]TriggerError), otherwise ErrTypeAssertionError is thrown. +func AssertRecurseTriggerErrorRequired(objSlice interface{}) error { + return AssertRecurseInterfaceRequired(objSlice, func(obj interface{}) error { + aTriggerError, ok := obj.(TriggerError) + if !ok { + return ErrTypeAssertionError + } + return AssertTriggerErrorRequired(aTriggerError) + }) +} diff --git a/server/openapi/model_trigger_result_trigger_result.go b/server/openapi/model_trigger_result_trigger_result.go index 6875d5a084..3d3fcc5e90 100644 --- a/server/openapi/model_trigger_result_trigger_result.go +++ b/server/openapi/model_trigger_result_trigger_result.go @@ -17,6 +17,8 @@ type TriggerResultTriggerResult struct { Traceid TraceidResponse `json:"traceid,omitempty"` Kafka KafkaResponse `json:"kafka,omitempty"` + + Error TriggerError `json:"error,omitempty"` } // AssertTriggerResultTriggerResultRequired checks if the required fields are not zero-ed @@ -33,6 +35,9 @@ func AssertTriggerResultTriggerResultRequired(obj TriggerResultTriggerResult) er if err := AssertKafkaResponseRequired(obj.Kafka); err != nil { return err } + if err := AssertTriggerErrorRequired(obj.Error); err != nil { + return err + } return nil } diff --git a/web/src/types/Generated.types.ts b/web/src/types/Generated.types.ts index 9652ac6c66..ec22d9021f 100644 --- a/web/src/types/Generated.types.ts +++ b/web/src/types/Generated.types.ts @@ -2053,8 +2053,15 @@ export interface external { grpc?: external["grpc.yaml"]["components"]["schemas"]["GRPCResponse"]; traceid?: external["traceid.yaml"]["components"]["schemas"]["TRACEIDResponse"]; kafka?: external["kafka.yaml"]["components"]["schemas"]["KafkaResponse"]; + error?: external["triggers.yaml"]["components"]["schemas"]["TriggerError"]; }; }; + TriggerError: { + connectionError?: boolean; + runningOnContainer?: boolean; + targetsLocalhost?: boolean; + message?: string; + }; }; }; operations: {}; From e4dd4a0b78f56a990fa4ca44ce13071b1fbd8c0f Mon Sep 17 00:00:00 2001 From: Sebastian Choren Date: Mon, 6 Nov 2023 12:52:50 -0300 Subject: [PATCH 11/19] fix(server): fix issues when running tests (#3336) --- go.mod | 3 +- go.sum | 2 - server/app/app.go | 2 +- server/executor/test_suite_runner_test.go | 2 +- server/http/mappings/tests.go | 23 ++-- server/test/run_repository.go | 104 +----------------- server/test/test_repository_test.go | 4 +- server/testdb/test_run_event_test.go | 2 +- server/testsuite/testsuite_repository_test.go | 6 +- .../testsuite_run_repository_test.go | 2 +- server/traces/span_entitiess.go | 19 +++- 11 files changed, 47 insertions(+), 122 deletions(-) diff --git a/go.mod b/go.mod index 7bcc123dc7..62b9cfd2b4 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,6 @@ require ( github.com/ohler55/ojg v1.14.4 github.com/opensearch-project/opensearch-go v1.1.0 github.com/orlangure/gnomock v0.20.0 - github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.9.1 github.com/prometheus/prometheus v1.8.2-0.20211217191541-41f1a8125e66 github.com/pterm/pterm v0.12.69 @@ -55,6 +54,7 @@ require ( github.com/spf13/viper v1.15.0 github.com/stretchr/testify v1.8.4 github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 + gitlab.com/metakeule/fmtdate v1.2.2 go.opencensus.io v0.24.0 go.opentelemetry.io/collector/component v0.80.0 go.opentelemetry.io/collector/config/configcompression v0.80.0 @@ -173,7 +173,6 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - gitlab.com/metakeule/fmtdate v1.2.2 // indirect go.opentelemetry.io/collector v0.80.0 // indirect go.opentelemetry.io/collector/config/configauth v0.80.0 // indirect go.opentelemetry.io/collector/config/confignet v0.80.0 // indirect diff --git a/go.sum b/go.sum index 8d74694863..83094c6260 100644 --- a/go.sum +++ b/go.sum @@ -1519,8 +1519,6 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= -github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= diff --git a/server/app/app.go b/server/app/app.go index a53ddc0e42..24c9d91dfe 100644 --- a/server/app/app.go +++ b/server/app/app.go @@ -228,7 +228,7 @@ func (app *App) Start(opts ...appOption) error { variableSetRepo := variableset.NewRepository(db) linterRepo := analyzer.NewRepository(db) testRepo := test.NewRepository(db) - runRepo := test.NewRunRepository(db, test.NewCache(instanceID, test.WithMetricMeter(meter))) + runRepo := test.NewRunRepository(db) testRunnerRepo := testrunner.NewRepository(db) tracesRepo := traces.NewTraceRepository(db) diff --git a/server/executor/test_suite_runner_test.go b/server/executor/test_suite_runner_test.go index 1176353e71..ebd90202aa 100644 --- a/server/executor/test_suite_runner_test.go +++ b/server/executor/test_suite_runner_test.go @@ -116,7 +116,7 @@ func runTestSuiteRunnerTest(t *testing.T, withErrors bool, assert func(t *testin subscriptionManager := subscription.NewManager() testRepo := test.NewRepository(rawDB) - runRepo := test.NewRunRepository(rawDB, test.NewCache("test")) + runRepo := test.NewRunRepository(rawDB) testRunner := &fakeTestRunner{ runRepo, diff --git a/server/http/mappings/tests.go b/server/http/mappings/tests.go index caf88ae9cd..668a0776c7 100644 --- a/server/http/mappings/tests.go +++ b/server/http/mappings/tests.go @@ -460,13 +460,22 @@ func (m Model) Trigger(in openapi.Trigger) trigger.Trigger { func (m Model) TriggerResult(in openapi.TriggerResult) trigger.TriggerResult { - return trigger.TriggerResult{ - Type: trigger.TriggerType(in.Type), - HTTP: m.HTTPResponse(in.TriggerResult.Http), - GRPC: m.GRPCResponse(in.TriggerResult.Grpc), - TraceID: m.TraceIDResponse(in.TriggerResult.Traceid), - Error: m.TriggerError(in.TriggerResult.Error), - } + tr := trigger.TriggerResult{ + Type: trigger.TriggerType(in.Type), + Error: m.TriggerError(in.TriggerResult.Error), + } + switch in.Type { + case "http": + tr.HTTP = m.HTTPResponse(in.TriggerResult.Http) + case "grpc": + tr.GRPC = m.GRPCResponse(in.TriggerResult.Grpc) + case "traceid": + tr.TraceID = m.TraceIDResponse(in.TriggerResult.Traceid) + case "kafka": + tr.Kafka = m.KafkaResponse(in.TriggerResult.Kafka) + } + + return tr } func (m Model) TriggerError(in openapi.TriggerError) *trigger.TriggerError { diff --git a/server/test/run_repository.go b/server/test/run_repository.go index 3a836f49c9..6390a69f42 100644 --- a/server/test/run_repository.go +++ b/server/test/run_repository.go @@ -5,7 +5,6 @@ import ( "database/sql" "encoding/json" "fmt" - "log" "strconv" "time" @@ -13,10 +12,6 @@ import ( "github.com/kubeshop/tracetest/server/pkg/id" "github.com/kubeshop/tracetest/server/pkg/sqlutil" "github.com/kubeshop/tracetest/server/variableset" - "github.com/patrickmn/go-cache" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/noop" "go.opentelemetry.io/otel/trace" ) @@ -33,94 +28,13 @@ type RunRepository interface { GetTestSuiteRunSteps(_ context.Context, _ id.ID, runID int) ([]Run, error) } -type Cache struct { - cache *cache.Cache - instanceID string - cacheLatencyHistogram metric.Int64Histogram -} - -type CacheConfig struct { - meter metric.Meter -} - -type CacheOption func(*CacheConfig) - -func WithMetricMeter(meter metric.Meter) CacheOption { - return func(c *CacheConfig) { - c.meter = meter - } -} - -func NewCache(instanceID string, opts ...CacheOption) *Cache { - cacheConfig := &CacheConfig{ - meter: noop.NewMeterProvider().Meter("noop"), - } - - for _, opt := range opts { - opt(cacheConfig) - } - - cacheLatencyHistogram, _ := cacheConfig.meter.Int64Histogram("tracetest.cache.latency") - - cache := &Cache{ - cache: cache.New(5*time.Minute, 10*time.Minute), - instanceID: instanceID, - cacheLatencyHistogram: cacheLatencyHistogram, - } - - return cache -} - -func (c *Cache) thisInstanceCacheKey(run Run) string { - return fmt.Sprintf("%s-%s-%d", c.instanceID, run.TestID, run.ID) -} - -func (c *Cache) lastInstanceCacheKey(ctx context.Context, run Run) string { - instanceID := c.instanceID - if instanceID := ctx.Value("LastInstanceID"); instanceID != nil { - instanceID = instanceID.(string) - } - - return fmt.Sprintf("%s-%s-%d", instanceID, run.TestID, run.ID) -} - -func (c *Cache) Set(_ context.Context, run Run) error { - log.Printf("testRunCache Update %s %d", run.TestID, run.ID) - c.cache.Set(c.thisInstanceCacheKey(run), run, cache.DefaultExpiration) - return nil -} - -func (c *Cache) Get(ctx context.Context, testID id.ID, runID int) (Run, bool) { - begin := time.Now() - key := c.lastInstanceCacheKey(ctx, Run{ID: runID, TestID: testID}) - cached, found := c.cache.Get(key) - - duration := time.Since(begin) - - attributeSet := attribute.NewSet( - attribute.String("object_type", "test_run"), - attribute.String("key", key), - attribute.Bool("hit", found), - ) - - c.cacheLatencyHistogram.Record(ctx, duration.Milliseconds(), metric.WithAttributeSet(attributeSet)) - - if !found { - return Run{}, false - } - - return cached.(Run), true -} - type runRepository struct { - db *sql.DB - cache *Cache + db *sql.DB } -func NewRunRepository(db *sql.DB, cache *Cache) RunRepository { +func NewRunRepository(db *sql.DB) RunRepository { return &runRepository{ - db: db, - cache: cache, + db: db, } } @@ -417,8 +331,6 @@ func (r *runRepository) UpdateRun(ctx context.Context, run Run) error { return fmt.Errorf("sql exec: %w", err) } - r.cache.Set(ctx, run) - return nil } @@ -501,11 +413,6 @@ var ( ) func (r *runRepository) GetRun(ctx context.Context, testID id.ID, runID int) (Run, error) { - cached, found := r.cache.Get(ctx, testID, runID) - if found { - return cached, nil - } - query, params := sqlutil.TenantWithPrefix(ctx, selectRunQuery+" WHERE id = $1 AND test_id = $2", "test_runs.", runID, testID) run, err := readRunRow(r.db.QueryRowContext(ctx, query, params...)) @@ -513,7 +420,6 @@ func (r *runRepository) GetRun(ctx context.Context, testID id.ID, runID int) (Ru return Run{}, fmt.Errorf("cannot read row: %w", err) } - r.cache.Set(ctx, run) return run, nil } @@ -665,7 +571,7 @@ func readRunRow(row scanner) (Run, error) { return Run{}, fmt.Errorf("cannot parse Results: %w", err) } - if jsonTrace != nil { + if jsonTrace != nil && string(jsonTrace) != "null" { err = json.Unmarshal(jsonTrace, &r.Trace) if err != nil { return Run{}, fmt.Errorf("cannot parse Trace: %w", err) @@ -749,7 +655,7 @@ func (r *runRepository) GetTestSuiteRunSteps(ctx context.Context, id id.ID, runI WHERE test_suite_run_steps.test_suite_run_id = $1 AND test_suite_run_steps.test_suite_run_test_suite_id = $2 ` query, params := sqlutil.TenantWithPrefix(ctx, query, "test_runs.", strconv.Itoa(runID), id) - query += ` ORDER BY test_runs.completed_at ASC` + query += ` ORDER BY test_runs.created_at ASC` stmt, err := r.db.Prepare(query) if err != nil { diff --git a/server/test/test_repository_test.go b/server/test/test_repository_test.go index 039f939173..70b8c9f2b3 100644 --- a/server/test/test_repository_test.go +++ b/server/test/test_repository_test.go @@ -88,7 +88,7 @@ func registerManagerFn(router *mux.Router, db *sql.DB) resourcemanager.Manager { func getScenarioPreparation(sample, secondSample, thirdSample test.Test) func(t *testing.T, op rmtest.Operation, manager resourcemanager.Manager) { return func(t *testing.T, op rmtest.Operation, manager resourcemanager.Manager) { testRepo := manager.Handler().(test.Repository) - testRunRepo := test.NewRunRepository(testRepo.DB(), test.NewCache("test")) + testRunRepo := test.NewRunRepository(testRepo.DB()) switch op { case rmtest.OperationGetSuccess, @@ -180,7 +180,7 @@ func TestIfDeleteTestsCascadeDeletes(t *testing.T) { defer db.Close() testRepository := test.NewRepository(db) - runRepository := test.NewRunRepository(db, test.NewCache("test")) + runRepository := test.NewRunRepository(db) transactionRepository := testsuite.NewRepository(db, testRepository) transactionRunRepository := testsuite.NewRunRepository(db, runRepository) diff --git a/server/testdb/test_run_event_test.go b/server/testdb/test_run_event_test.go index 9e15186881..798e6823a2 100644 --- a/server/testdb/test_run_event_test.go +++ b/server/testdb/test_run_event_test.go @@ -17,7 +17,7 @@ func TestRunEvents(t *testing.T) { defer rawDB.Close() testRepo := test.NewRepository(rawDB) - testRunRepo := test.NewRunRepository(rawDB, test.NewCache("test")) + testRunRepo := test.NewRunRepository(rawDB) test1 := createTestWithName(t, testRepo, "test 1") diff --git a/server/testsuite/testsuite_repository_test.go b/server/testsuite/testsuite_repository_test.go index e5e1ff2a25..13cf13846a 100644 --- a/server/testsuite/testsuite_repository_test.go +++ b/server/testsuite/testsuite_repository_test.go @@ -63,7 +63,7 @@ func createRun(runRepository test.RunRepository, t test.Test) test.Run { func setupTestSuiteFixture(t *testing.T, db *sql.DB) testSuiteFixture { testsDB := test.NewRepository(db) - runDB := test.NewRunRepository(db, test.NewCache("test")) + runDB := test.NewRunRepository(db) fixture := testSuiteFixture{} @@ -142,7 +142,7 @@ func TestDeleteTestsRelatedToTestSuite(t *testing.T) { defer db.Close() testRepository := test.NewRepository(db) - runRepository := test.NewRunRepository(db, test.NewCache("test")) + runRepository := test.NewRunRepository(db) testSuiteRepo := testsuite.NewRepository(db, testRepository) testSuiteRunRepo := testsuite.NewRunRepository(db, runRepository) @@ -208,7 +208,7 @@ func TestTestSuites(t *testing.T) { }, Prepare: func(t *testing.T, op rmtests.Operation, manager resourcemanager.Manager) { transactionRepo := manager.Handler().(*testsuite.Repository) - runRepository := test.NewRunRepository(transactionRepo.DB(), test.NewCache("test")) + runRepository := test.NewRunRepository(transactionRepo.DB()) runRepo := testsuite.NewRunRepository(transactionRepo.DB(), runRepository) switch op { diff --git a/server/testsuite/testsuite_run_repository_test.go b/server/testsuite/testsuite_run_repository_test.go index 1dcfcd178b..d0628a9af5 100644 --- a/server/testsuite/testsuite_run_repository_test.go +++ b/server/testsuite/testsuite_run_repository_test.go @@ -37,7 +37,7 @@ func getRepos() (*testsuite.Repository, *testsuite.RunRepository, test.Repositor db := testmock.CreateMigratedDatabase() testRepo := test.NewRepository(db) - testRunRepo := test.NewRunRepository(db, test.NewCache("test")) + testRunRepo := test.NewRunRepository(db) transactionRepo := testsuite.NewRepository(db, testRepo) runRepo := testsuite.NewRunRepository(db, testRunRepo) diff --git a/server/traces/span_entitiess.go b/server/traces/span_entitiess.go index a3d2ed4719..90edcf6bfe 100644 --- a/server/traces/span_entitiess.go +++ b/server/traces/span_entitiess.go @@ -112,6 +112,15 @@ type encodedSpan struct { Children []encodedSpan } +const nilSpanID = "0000000000000000" + +func (es encodedSpan) isValidID() bool { + if es.ID == nilSpanID || es.ID == "" { + return false + } + return true +} + func (s Span) IsZero() bool { return !s.ID.IsValid() } @@ -150,9 +159,13 @@ func (s *Span) UnmarshalJSON(data []byte) error { } func (s *Span) decodeSpan(aux encodedSpan) error { - sid, err := trace.SpanIDFromHex(aux.ID) - if err != nil { - return fmt.Errorf("unmarshal span: %w", err) + sid := trace.SpanID{} + if aux.isValidID() { + var err error + sid, err = trace.SpanIDFromHex(aux.ID) + if err != nil { + return fmt.Errorf("unmarshal span: %w", err) + } } children, err := decodeChildren(s, aux.Children, getCache()) From 72a9e3dbac38eaccb4b2182120ca8740f95b4a80 Mon Sep 17 00:00:00 2001 From: Daniel Baptista Dias Date: Mon, 6 Nov 2023 15:22:21 -0300 Subject: [PATCH 12/19] feat: adding flags for token, environment and organization (#3337) adding flags for environment and organization --- cli/cmd/configure_cmd.go | 25 ++++++++++++++++++++++--- cli/config/configurator.go | 11 +++++++++-- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/cli/cmd/configure_cmd.go b/cli/cmd/configure_cmd.go index 68c6f93455..23545d09e1 100644 --- a/cli/cmd/configure_cmd.go +++ b/cli/cmd/configure_cmd.go @@ -34,6 +34,18 @@ var configureCmd = &cobra.Command{ flags.Endpoint = configParams.Endpoint } + if flagProvided(cmd, "token") { + flags.Token = configParams.Token + } + + if flagProvided(cmd, "environment") { + flags.EnvironmentID = configParams.EnvironmentID + } + + if flagProvided(cmd, "organization") { + flags.OrganizationID = configParams.OrganizationID + } + err = configurator.Start(ctx, config, flags) return "", err })), @@ -48,14 +60,21 @@ func init() { configureCmd.PersistentFlags().BoolVarP(&configParams.Global, "global", "g", false, "configuration will be saved in your home dir") configureCmd.PersistentFlags().StringVarP(&configParams.Endpoint, "endpoint", "e", "", "set the value for the endpoint, so the CLI won't ask for this value") + configureCmd.PersistentFlags().StringVarP(&configParams.Token, "token", "t", "", "set authetication with token, so the CLI won't ask you for authentication") + configureCmd.PersistentFlags().StringVarP(&configParams.EnvironmentID, "environment", "", "", "set environmentID, so the CLI won't ask you for it") + configureCmd.PersistentFlags().StringVarP(&configParams.OrganizationID, "organization", "", "", "set organizationID, so the CLI won't ask you for it") + configureCmd.PersistentFlags().BoolVarP(&configParams.CI, "ci", "", false, "if cloud is used, don't ask for authentication") rootCmd.AddCommand(configureCmd) } type configureParameters struct { - Endpoint string - Global bool - CI bool + Endpoint string + Global bool + CI bool + Token string + OrganizationID string + EnvironmentID string } func (p configureParameters) Validate(cmd *cobra.Command, args []string) []error { diff --git a/cli/config/configurator.go b/cli/config/configurator.go index 52236e04a8..808b697b8c 100644 --- a/cli/config/configurator.go +++ b/cli/config/configurator.go @@ -117,8 +117,15 @@ func (c Configurator) Start(ctx context.Context, prev Config, flags ConfigFlags) return err } - flags.OrganizationID = claims["organization_id"].(string) - flags.EnvironmentID = claims["environment_id"].(string) + organizationId := claims["organization_id"].(string) + environmentId := claims["environment_id"].(string) + + if organizationId != "" { + flags.OrganizationID = organizationId + } + if environmentId != "" { + flags.EnvironmentID = environmentId + } } if flags.AgentApiKey != "" { From 7144a9208f9925f172c0d52cdbd61ceec67d1f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adnan=20Rahi=C4=87?= Date: Mon, 6 Nov 2023 20:44:38 +0100 Subject: [PATCH 13/19] docs(migrate to mdx): Update live examples section (#3333) docs(migrate to mdx): live examples section --- .../{overview.md => overview.mdx} | 22 ++++++++++---- ...art.md => add-item-into-shopping-cart.mdx} | 14 ++++++++- ...ts.md => check-shopping-cart-contents.mdx} | 16 ++++++++-- .../use-cases/{checkout.md => checkout.mdx} | 16 ++++++++-- ...oducts.md => get-recommended-products.mdx} | 14 ++++++++- ...oducts.md => user-purchasing-products.mdx} | 30 +++++++++++++------ .../pokeshop/{overview.md => overview.mdx} | 24 +++++++++++---- .../{add-pokemon.md => add-pokemon.mdx} | 14 ++++++++- ...pokemon-by-id.md => get-pokemon-by-id.mdx} | 14 ++++++++- ...ream.md => import-pokemon-from-stream.mdx} | 17 ++++++++++- .../{import-pokemon.md => import-pokemon.mdx} | 17 +++++++++-- .../{list-pokemon.md => list-pokemon.mdx} | 14 ++++++++- docs/sidebars.js | 18 +++++------ 13 files changed, 188 insertions(+), 42 deletions(-) rename docs/docs/live-examples/opentelemetry-store/{overview.md => overview.mdx} (79%) rename docs/docs/live-examples/opentelemetry-store/use-cases/{add-item-into-shopping-cart.md => add-item-into-shopping-cart.mdx} (84%) rename docs/docs/live-examples/opentelemetry-store/use-cases/{check-shopping-cart-contents.md => check-shopping-cart-contents.mdx} (85%) rename docs/docs/live-examples/opentelemetry-store/use-cases/{checkout.md => checkout.mdx} (89%) rename docs/docs/live-examples/opentelemetry-store/use-cases/{get-recommended-products.md => get-recommended-products.mdx} (86%) rename docs/docs/live-examples/opentelemetry-store/use-cases/{user-purchasing-products.md => user-purchasing-products.mdx} (81%) rename docs/docs/live-examples/pokeshop/{overview.md => overview.mdx} (67%) rename docs/docs/live-examples/pokeshop/use-cases/{add-pokemon.md => add-pokemon.mdx} (85%) rename docs/docs/live-examples/pokeshop/use-cases/{get-pokemon-by-id.md => get-pokemon-by-id.mdx} (90%) rename docs/docs/live-examples/pokeshop/use-cases/{import-pokemon-from-stream.md => import-pokemon-from-stream.mdx} (87%) rename docs/docs/live-examples/pokeshop/use-cases/{import-pokemon.md => import-pokemon.mdx} (89%) rename docs/docs/live-examples/pokeshop/use-cases/{list-pokemon.md => list-pokemon.mdx} (86%) diff --git a/docs/docs/live-examples/opentelemetry-store/overview.md b/docs/docs/live-examples/opentelemetry-store/overview.mdx similarity index 79% rename from docs/docs/live-examples/opentelemetry-store/overview.md rename to docs/docs/live-examples/opentelemetry-store/overview.mdx index e7156a220e..e1551125dc 100644 --- a/docs/docs/live-examples/opentelemetry-store/overview.md +++ b/docs/docs/live-examples/opentelemetry-store/overview.mdx @@ -1,4 +1,16 @@ -# OpenTelemetry Astronomy Shop Demo +--- +id: overview +title: OpenTelemetry Astronomy Shop Demo +description: The OpenTelemetry Demo is an example application published by the OpenTelemtry CNCF project. The Tracetest team has made several key contributions to this project, including providing a full suite of end to end tests. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- The OpenTelemetry Demo is an example application published by the OpenTelemtry CNCF project. It implements an Astronomy shop in a set of microservices in different languages with OpenTelemetry enabled, intended to be used as an example of OpenTelemetry instrumentation and observability. The Tracetest team has made several key contributions to this project, including providing a full suite of end to end tests. @@ -106,10 +118,10 @@ Tracetest will be started on [http://localhost:11633](http://localhost:11633) as ## Use Cases -- [Add item into shopping cart](./use-cases/add-item-into-shopping-cart.md): Simulate a user choosing an item and adding it to the shopping cart. -- [Check shopping cart content](./use-cases/check-shopping-cart-contents.md): Simulate a user choosing different products and checking the shopping cart later. -- [Checkout](./use-cases/checkout.md): Simulates a user choosing a product and later doing a checkout of that product, with billing and shipping info. -- [Get recommended products](./use-cases/get-recommended-products.md): Simulates a user querying for recommended products. +- [Add item into shopping cart](/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart): Simulate a user choosing an item and adding it to the shopping cart. +- [Check shopping cart content](/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents): Simulate a user choosing different products and checking the shopping cart later. +- [Checkout](/live-examples/opentelemetry-store/use-cases/checkout): Simulates a user choosing a product and later doing a checkout of that product, with billing and shipping info. +- [Get recommended products](/live-examples/opentelemetry-store/use-cases/get-recommended-products): Simulates a user querying for recommended products. ## System Architecture diff --git a/docs/docs/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart.md b/docs/docs/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart.mdx similarity index 84% rename from docs/docs/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart.md rename to docs/docs/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart.mdx index d7dcf0a0d5..7adef1e61c 100644 --- a/docs/docs/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart.md +++ b/docs/docs/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart.mdx @@ -1,4 +1,16 @@ -# OpenTelemetry Store - Add item into the shopping cart +--- +id: add-item-into-shopping-cart +title: OpenTelemetry Store - Add item into the shopping cart +description: The OpenTelemetry Demo is an example application published by the OpenTelemtry CNCF project. This use case covers adding a product from the catalog into a shopping cart. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- In this use case, we want to validate the following story: diff --git a/docs/docs/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents.md b/docs/docs/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents.mdx similarity index 85% rename from docs/docs/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents.md rename to docs/docs/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents.mdx index 702da0da2d..a5f5dfb9f0 100644 --- a/docs/docs/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents.md +++ b/docs/docs/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents.mdx @@ -1,4 +1,16 @@ -# OpenTelemetry Store - Check shopping cart contents +--- +id: check-shopping-cart-contents +title: OpenTelemetry Store - Check shopping cart contents +description: The OpenTelemetry Demo is an example application published by the OpenTelemtry CNCF project. This use case covers seeing all the products in the shopping cart. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- In this use case, we want to validate the following story: @@ -36,7 +48,7 @@ You can trigger this use case by calling the endpoint `GET /api/cart?sessionId={ } ``` -If it is the first time that you are calling this endpoint, to see an item into the shopping cart you need first to [Add item into shopping cart](./add-item-into-shopping-cart.md). +If it is the first time that you are calling this endpoint, to see an item into the shopping cart you need first to [Add item into shopping cart](/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart). ## Building a Test for This Scenario diff --git a/docs/docs/live-examples/opentelemetry-store/use-cases/checkout.md b/docs/docs/live-examples/opentelemetry-store/use-cases/checkout.mdx similarity index 89% rename from docs/docs/live-examples/opentelemetry-store/use-cases/checkout.md rename to docs/docs/live-examples/opentelemetry-store/use-cases/checkout.mdx index 089602a8c0..c49a4906c8 100644 --- a/docs/docs/live-examples/opentelemetry-store/use-cases/checkout.md +++ b/docs/docs/live-examples/opentelemetry-store/use-cases/checkout.mdx @@ -1,4 +1,16 @@ -# OpenTelemetry Store - Checkout +--- +id: checkout +title: OpenTelemetry Store - Checkout +description: The OpenTelemetry Demo is an example application published by the OpenTelemtry CNCF project. This use case covers paying for products in a shopping cart. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- In this use case, we want to validate the following story: @@ -53,7 +65,7 @@ It should return a payload similar to this: } ``` -If it is the first time that you are calling this endpoint, to see an item into the shopping cart you need first to [Add item into shopping cart](./add-item-into-shopping-cart.md). +If it is the first time that you are calling this endpoint, to see an item into the shopping cart you need first to [Add item into shopping cart](/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart). ## Building a Test for This Scenario diff --git a/docs/docs/live-examples/opentelemetry-store/use-cases/get-recommended-products.md b/docs/docs/live-examples/opentelemetry-store/use-cases/get-recommended-products.mdx similarity index 86% rename from docs/docs/live-examples/opentelemetry-store/use-cases/get-recommended-products.md rename to docs/docs/live-examples/opentelemetry-store/use-cases/get-recommended-products.mdx index 8f4b2d15fd..b3ef506d0f 100644 --- a/docs/docs/live-examples/opentelemetry-store/use-cases/get-recommended-products.md +++ b/docs/docs/live-examples/opentelemetry-store/use-cases/get-recommended-products.mdx @@ -1,4 +1,16 @@ -# OpenTelemetry Store - Get recommended products +--- +id: get-recommended-products +title: OpenTelemetry Store - Get recommended products +description: The OpenTelemetry Demo is an example application published by the OpenTelemtry CNCF project. This use case covers viewing recommended products before adding them to the shopping cart. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- In this use case, we want to validate the following story: diff --git a/docs/docs/live-examples/opentelemetry-store/use-cases/user-purchasing-products.md b/docs/docs/live-examples/opentelemetry-store/use-cases/user-purchasing-products.mdx similarity index 81% rename from docs/docs/live-examples/opentelemetry-store/use-cases/user-purchasing-products.md rename to docs/docs/live-examples/opentelemetry-store/use-cases/user-purchasing-products.mdx index 1c113bb21a..44407d88e1 100644 --- a/docs/docs/live-examples/opentelemetry-store/use-cases/user-purchasing-products.md +++ b/docs/docs/live-examples/opentelemetry-store/use-cases/user-purchasing-products.mdx @@ -1,4 +1,16 @@ -# OpenTelemetry Store - User Purchasing Products +--- +id: user-purchasing-products +title: OpenTelemetry Store - User Purchasing Products +description: The OpenTelemetry Demo is an example application published by the OpenTelemtry CNCF project. This use case covers viewing recommended products before adding them to the shopping cart. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- In this use case, we want to validate the following story: @@ -9,10 +21,10 @@ So I can have it shipped to my home ``` Something interesting about this process is that it is a composition of many of the previous use cases, executed in sequence: -1. [Get Recommended Products](./get-recommended-products.md) -2. [Add Item into Shopping Cart](./add-item-into-shopping-cart.md) -3. [Check Shopping Cart Contents](./check-shopping-cart-contents.md) -4. [Checkout](./checkout.md) +1. [Get Recommended Products](/live-examples/opentelemetry-store/use-cases/get-recommended-products) +2. [Add Item into Shopping Cart](/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart) +3. [Check Shopping Cart Contents](/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents) +4. [Checkout](/live-examples/opentelemetry-store/use-cases/checkout) So in this case, we need to trigger four tests in sequence to achieve test the entire scenario and make these tests share data. @@ -34,7 +46,7 @@ USER_ID=2491f868-88f1-4345-8836-d5d8511a9f83 ### Creating Tests -After creating the environment file, we will create a test for each step, starting with [Get Recommended Products](./get-recommended-products.md), which will be saved as `get-recommended-products.yaml`: +After creating the environment file, we will create a test for each step, starting with [Get Recommended Products](/live-examples/opentelemetry-store/use-cases/get-recommended-products), which will be saved as `get-recommended-products.yaml`: ```yaml type: Test @@ -63,7 +75,7 @@ spec: Note that we have one important changes here: we are now using environment variables on the definition, like `${var:OTEL_API_URL}` and `${var:USER_ID}` on the trigger section and an output to fetch the first `${var:PRODUCT_ID}` that the user chose. This new environment variable will be used in the next tests. -The next step is to define the [Add Item into Shopping Cart](./add-item-into-shopping-cart.md) test, which will be saved as `add-product-into-shopping-cart.yaml`: +The next step is to define the [Add Item into Shopping Cart](/live-examples/opentelemetry-store/use-cases/add-item-into-shopping-cart) test, which will be saved as `add-product-into-shopping-cart.yaml`: ```yaml type: Test @@ -90,7 +102,7 @@ spec: - attr:tracetest.selected_spans.count >= 1 ``` -After that, we will [Check Shopping Cart Contents](./check-shopping-cart-contents.md) (on `check-shopping-cart-contents.yaml`), simulating a user validating the products selected before finishing the purchase: +After that, we will [Check Shopping Cart Contents](/live-examples/opentelemetry-store/use-cases/check-shopping-cart-contents) (on `check-shopping-cart-contents.yaml`), simulating a user validating the products selected before finishing the purchase: ```yaml type: Test @@ -115,7 +127,7 @@ spec: - attr:tracetest.response.body | json_path '$.items.length' >= 1 ``` -And finally, we have the [Checkout](./checkout.md) action (`checkout.yaml`), where the user inputs the billing and shipping info and finishes buying the item in the shopping cart: +And finally, we have the [Checkout](/live-examples/opentelemetry-store/use-cases/checkout) action (`checkout.yaml`), where the user inputs the billing and shipping info and finishes buying the item in the shopping cart: ```yaml type: Test diff --git a/docs/docs/live-examples/pokeshop/overview.md b/docs/docs/live-examples/pokeshop/overview.mdx similarity index 67% rename from docs/docs/live-examples/pokeshop/overview.md rename to docs/docs/live-examples/pokeshop/overview.mdx index cb15581633..d68a681151 100644 --- a/docs/docs/live-examples/pokeshop/overview.md +++ b/docs/docs/live-examples/pokeshop/overview.mdx @@ -1,4 +1,16 @@ -# Pokeshop API +--- +id: overview +title: Pokeshop API Demo +description: As a testing ground, the Tracetest team has implemented a sample API instrumented with OpenTelemetry around the PokeAPI. The reason is to provide a microservice-based system that contains message queues, cache layers, databases, and CRUD operations. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- As a testing ground, the team at Tracetest has implemented a sample instrumented API around the [PokeAPI](https://pokeapi.co/). @@ -20,11 +32,11 @@ Want to run tests against the Pokeshop Demo without installing it locally? Click We have three use cases that use each component of this structure and that can be observed via Open Telemetry and tested with Tracetest. Each one is triggered by an API call to their respective endpoint: -- [Add Pokemon](./use-cases/add-pokemon.md): Add a new Pokemon only relying on user input into the database. -- [Get Pokemon by ID](./use-cases/get-pokemon-by-id.md): Given a Pokemon ID, this endpoint returns the data of a Pokemon. If the same Pokemon was queried, the API will use its cache to return it. -- [List Pokemon](./use-cases/list-pokemon.md): Lists all Pokemons registered into Pokeshop. -- [Import Pokemon](./use-cases/import-pokemon.md): Given a Pokemon ID, this endpoint does an async process, going to PokeAPI to get Pokemon data and adding it to the database. -- [Import Pokemon from Stream](./use-cases/import-pokemon-from-stream.md): Listening to a Stream, this use case also does an async process, going to PokeAPI to get Pokemon data and adding it to the database. +- [Add Pokemon](/live-examples/pokeshop/use-cases/add-pokemon): Add a new Pokemon only relying on user input into the database. +- [Get Pokemon by ID](/live-examples/pokeshop/use-cases/get-pokemon-by-id): Given a Pokemon ID, this endpoint returns the data of a Pokemon. If the same Pokemon was queried, the API will use its cache to return it. +- [List Pokemon](/live-examples/pokeshop/use-cases/list-pokemon): Lists all Pokemons registered into Pokeshop. +- [Import Pokemon](/live-examples/pokeshop/use-cases/import-pokemon): Given a Pokemon ID, this endpoint does an async process, going to PokeAPI to get Pokemon data and adding it to the database. +- [Import Pokemon from Stream](/live-examples/pokeshop/use-cases/import-pokemon-from-stream): Listening to a Stream, this use case also does an async process, going to PokeAPI to get Pokemon data and adding it to the database. ## System Architecture diff --git a/docs/docs/live-examples/pokeshop/use-cases/add-pokemon.md b/docs/docs/live-examples/pokeshop/use-cases/add-pokemon.mdx similarity index 85% rename from docs/docs/live-examples/pokeshop/use-cases/add-pokemon.md rename to docs/docs/live-examples/pokeshop/use-cases/add-pokemon.mdx index 5bb5c0cbf7..08a369da1b 100644 --- a/docs/docs/live-examples/pokeshop/use-cases/add-pokemon.md +++ b/docs/docs/live-examples/pokeshop/use-cases/add-pokemon.mdx @@ -1,4 +1,16 @@ -# Pokeshop API - Add Pokemon +--- +id: add-pokemon +title: Pokeshop API - Add Pokemon +description: As a testing ground, the Tracetest team has implemented a sample API instrumented with OpenTelemetry around the PokeAPI. This use case showcases a simple example of an API call where call data is validated and persisted into a database. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- This use case showcases a simple example of an API call where call data is validated and persisted into a database. diff --git a/docs/docs/live-examples/pokeshop/use-cases/get-pokemon-by-id.md b/docs/docs/live-examples/pokeshop/use-cases/get-pokemon-by-id.mdx similarity index 90% rename from docs/docs/live-examples/pokeshop/use-cases/get-pokemon-by-id.md rename to docs/docs/live-examples/pokeshop/use-cases/get-pokemon-by-id.mdx index ea616d340a..c8e5db4224 100644 --- a/docs/docs/live-examples/pokeshop/use-cases/get-pokemon-by-id.md +++ b/docs/docs/live-examples/pokeshop/use-cases/get-pokemon-by-id.mdx @@ -1,4 +1,16 @@ -# Pokeshop API - Get Pokemon by ID +--- +id: get-pokemon-by-id +title: Pokeshop API - Get Pokemon by ID +description: As a testing ground, the Tracetest team has implemented a sample API instrumented with OpenTelemetry around the PokeAPI. This use case retrieves a specific Pokemon from the cache if it is cached or from the database (Postgres) also populating the cache. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- This use case retrieves a specific Pokemon from the cache if it is cached or from the database (Postgres) also populating the cache. The idea of this query is to showcase a straightforward scenario, where the API layer receives a request from the outside and needs to evaluate a different behavior depending of its dependencies. diff --git a/docs/docs/live-examples/pokeshop/use-cases/import-pokemon-from-stream.md b/docs/docs/live-examples/pokeshop/use-cases/import-pokemon-from-stream.mdx similarity index 87% rename from docs/docs/live-examples/pokeshop/use-cases/import-pokemon-from-stream.md rename to docs/docs/live-examples/pokeshop/use-cases/import-pokemon-from-stream.mdx index 19595bcde1..83ffdff1f9 100644 --- a/docs/docs/live-examples/pokeshop/use-cases/import-pokemon-from-stream.md +++ b/docs/docs/live-examples/pokeshop/use-cases/import-pokemon-from-stream.mdx @@ -1,8 +1,21 @@ -# Pokeshop API - Import Pokemon from Stream +--- +id: import-pokemon-from-stream +title: Pokeshop API - Import Pokemon from Stream +description: As a testing ground, the Tracetest team has implemented a sample API instrumented with OpenTelemetry around the PokeAPI. This use case showcases a more complex scenario involving an async process. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- This use case showcases a more complex scenario involving an async process. Usually, when working with microservices, there are use cases where some of the processing needs to happen asynchronously. For example, when triggering a user notification, generating reports or processing a payment order. With this endpoint, we provide an example of how users can implement trace-based testing for such scenarios. Here the process listens to a stream, and whenever an event is read from it, the following process is triggered: + ```mermaid sequenceDiagram participant Stream as Kafka @@ -20,6 +33,7 @@ sequenceDiagram ``` You can trigger this use case by sending a message to Kafka on the `pokemon` topic with the following message value: + ```json { "id": 143 @@ -29,6 +43,7 @@ You can trigger this use case by sending a message to Kafka on the `pokemon` top ## Building a Test for This Scenario Using Tracetest, we can [create a test](/web-ui/creating-tests) that will produce a message to Kafka on `pokemon` topic and validate the following properties: + - The worker should read the import task. - PokeAPI should return a valid response. - The database should respond with low latency (< 200ms). diff --git a/docs/docs/live-examples/pokeshop/use-cases/import-pokemon.md b/docs/docs/live-examples/pokeshop/use-cases/import-pokemon.mdx similarity index 89% rename from docs/docs/live-examples/pokeshop/use-cases/import-pokemon.md rename to docs/docs/live-examples/pokeshop/use-cases/import-pokemon.mdx index b968dca90f..3e8ee8db8a 100644 --- a/docs/docs/live-examples/pokeshop/use-cases/import-pokemon.md +++ b/docs/docs/live-examples/pokeshop/use-cases/import-pokemon.mdx @@ -1,8 +1,21 @@ -# Pokeshop API - Import Pokemon +--- +id: import-pokemon +title: Pokeshop API - Import Pokemon +description: As a testing ground, the Tracetest team has implemented a sample API instrumented with OpenTelemetry around the PokeAPI. This use case showcases a more complex scenario involving an async process. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- This use case showcases a more complex scenario involving an async process. Usually, when working with microservices, there are use cases where some of the processing needs to happen asynchronously, for example, when triggering a user notification, generating reports or processing a payment order. With this endpoint, we provide an example of how users can implement trace-based testing for such scenarios. -Here the process is split into two phases: +Here the process is split into two phases: + 1. An API call that enqueues an import request to a queue. ```mermaid sequenceDiagram diff --git a/docs/docs/live-examples/pokeshop/use-cases/list-pokemon.md b/docs/docs/live-examples/pokeshop/use-cases/list-pokemon.mdx similarity index 86% rename from docs/docs/live-examples/pokeshop/use-cases/list-pokemon.md rename to docs/docs/live-examples/pokeshop/use-cases/list-pokemon.mdx index 5bf44e305b..5c4d874450 100644 --- a/docs/docs/live-examples/pokeshop/use-cases/list-pokemon.md +++ b/docs/docs/live-examples/pokeshop/use-cases/list-pokemon.mdx @@ -1,4 +1,16 @@ -# Pokeshop API - List Pokemon +--- +id: list-pokemon +title: Pokeshop API - List Pokemon +description: As a testing ground, the Tracetest team has implemented a sample API instrumented with OpenTelemetry around the PokeAPI. This use case retrieves the list of Pokemon directly from the database (Postgres) based on the provided query through the API. +hide_table_of_contents: false +keywords: + - tracetest + - trace-based testing + - observability + - distributed tracing + - testing +image: https://res.cloudinary.com/djwdcmwdz/image/upload/v1698686403/docs/Blog_Thumbnail_14_rsvkmo.jpg +--- This use case retrieves the list of Pokemon directly from the database (Postgres) based on the provided query through the API. The purpose of this query is to showcase a straightforward scenario, where the API layer receives a request from the outside and needs to trigger a database query to get some data and return it to the client. diff --git a/docs/sidebars.js b/docs/sidebars.js index 943c71af3d..4289e08811 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -26,12 +26,11 @@ const sidebars = { { type: "category", label: "OpenTelemetry Store Demo", + link: { + type: "doc", + id: "live-examples/opentelemetry-store/overview" + }, items: [ - { - type: "doc", - id: "live-examples/opentelemetry-store/overview", - label: "Overview", - }, { type: "category", label: "Use Cases", @@ -68,12 +67,11 @@ const sidebars = { { type: "category", label: "Pokeshop API Demo", + link: { + type: "doc", + id: "live-examples/pokeshop/overview" + }, items: [ - { - type: "doc", - id: "live-examples/pokeshop/overview", - label: "Overview", - }, { type: "category", label: "Use Cases", From 540a872e57ad22372575d687182659da7ac1bf51 Mon Sep 17 00:00:00 2001 From: Oscar Reyes Date: Tue, 7 Nov 2023 11:47:26 -0600 Subject: [PATCH 14/19] fix(UI): Fixing DataStore selection bug (#3339) --- .../DataStoreForm/DataStoreSelectionInput.tsx | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/web/src/components/Settings/DataStoreForm/DataStoreSelectionInput.tsx b/web/src/components/Settings/DataStoreForm/DataStoreSelectionInput.tsx index 89e382bd07..679e3ac0d7 100644 --- a/web/src/components/Settings/DataStoreForm/DataStoreSelectionInput.tsx +++ b/web/src/components/Settings/DataStoreForm/DataStoreSelectionInput.tsx @@ -1,4 +1,5 @@ import {Popover, Tabs} from 'antd'; +import {useCallback} from 'react'; import {noop} from 'lodash'; import {useTheme} from 'styled-components'; import {ConfigMode, SupportedDataStores} from 'types/DataStore.types'; @@ -25,8 +26,17 @@ const DataStoreSelectionInput = ({onChange = noop, value = SupportedDataStores.J const {dataStoreConfig} = useSettingsValues(); const configuredDataStoreType = dataStoreConfig.defaultDataStore.type; + const handleChange = useCallback( + dataStore => { + const isDisabled = isLocalModeEnabled && dataStore !== SupportedDataStores.Agent; + + if (!isDisabled) onChange(dataStore); + }, + [isLocalModeEnabled, onChange] + ); + return ( - + {supportedDataStoreList.map(dataStore => { if (dataStore === SupportedDataStores.Agent && !getFlag(Flag.IsAgentDataStoreEnabled)) { return null; @@ -40,12 +50,7 @@ const DataStoreSelectionInput = ({onChange = noop, value = SupportedDataStores.J (isDisabled ? noop() : onChange(dataStore))} - > + {isDisabled ? ( From d2abf0efa94842f9080823685dadbcc482ff516c Mon Sep 17 00:00:00 2001 From: Matheus Nogueira Date: Tue, 7 Nov 2023 14:47:57 -0300 Subject: [PATCH 15/19] fix: trigger result error handling (#3340) --- server/executor/trigger_result_processor_worker.go | 14 ++++++++------ server/test/trigger/trigger_json.go | 4 +++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/server/executor/trigger_result_processor_worker.go b/server/executor/trigger_result_processor_worker.go index c4e94e2342..f7649e950e 100644 --- a/server/executor/trigger_result_processor_worker.go +++ b/server/executor/trigger_result_processor_worker.go @@ -85,15 +85,17 @@ func (r triggerResultProcessorWorker) ProcessItem(ctx context.Context, job Job) Type: "run_update", Content: RunResult{Run: job.Run, Err: err}, }) - } else { - err := r.eventEmitter.Emit(ctx, events.TriggerExecutionSuccess(job.Run.TestID, job.Run.ID)) - if err != nil { - r.handleDBError(job.Run, err) - } + + r.handleDBError(job.Run, r.updater.Update(ctx, job.Run)) + return } - job.Run.State = test.RunStateAwaitingTrace + err := r.eventEmitter.Emit(ctx, events.TriggerExecutionSuccess(job.Run.TestID, job.Run.ID)) + if err != nil { + r.handleDBError(job.Run, err) + } + job.Run.State = test.RunStateAwaitingTrace r.handleDBError(job.Run, r.updater.Update(ctx, job.Run)) r.outputQueue.Enqueue(ctx, job) diff --git a/server/test/trigger/trigger_json.go b/server/test/trigger/trigger_json.go index cd2bca5121..c56f42b621 100644 --- a/server/test/trigger/trigger_json.go +++ b/server/test/trigger/trigger_json.go @@ -120,10 +120,11 @@ type triggerResultV2 struct { GRPC *GRPCResponse `json:"grpc,omitempty"` TraceID *TraceIDResponse `json:"traceid,omitempty"` Kafka *KafkaResponse `json:"kafka,omitempty"` + Error *TriggerError `json:"error,omitempty"` } func (tr *triggerResultV2) valid() bool { - return tr.HTTP != nil || tr.GRPC != nil || tr.TraceID != nil || tr.Kafka != nil + return tr.HTTP != nil || tr.GRPC != nil || tr.TraceID != nil || tr.Kafka != nil || tr.Error != nil } func (t *TriggerResult) UnmarshalJSON(data []byte) error { @@ -136,6 +137,7 @@ func (t *TriggerResult) UnmarshalJSON(data []byte) error { t.GRPC = v2.GRPC t.TraceID = v2.TraceID t.Kafka = v2.Kafka + t.Error = v2.Error return nil } From 3c24e6ea23510f2f2fd19b2ac970ffb6fc1951e6 Mon Sep 17 00:00:00 2001 From: Matheus Nogueira Date: Thu, 9 Nov 2023 19:18:50 -0300 Subject: [PATCH 16/19] feat: make agent reconnect in case of connection dropping (#3342) * feat: make agent reconnect in case of connection dropping * fix panic * fix(agent): use mutex for reconnecting client * fix tests * remove log * fix reconnection logic * add retry-go * ignore EOF errors * set max retries to 3 in grpc server mock * fix: reconnection logic * remove unused method * PR patches * fix build --- agent/client/client.go | 69 ++++++++++++++++++- agent/client/connector.go | 37 +++++++--- agent/client/default_listeners.go | 23 +++++++ agent/client/mocks/grpc_server.go | 34 +++++++-- agent/client/options.go | 8 +++ ...workflow_listen_for_ds_connection_tests.go | 14 ++-- .../workflow_listen_for_poll_requests.go | 14 ++-- .../workflow_listen_for_poll_requests_test.go | 1 + .../workflow_listen_for_trigger_requests.go | 14 ++-- ...rkflow_listen_for_trigger_requests_test.go | 1 + agent/client/workflow_ping.go | 19 ++++- agent/client/workflow_send_trace_test.go | 1 + .../workflow_send_trigger_response_test.go | 1 + agent/client/workflow_shutdown.go | 14 ++-- agent/client/workflow_shutdown_test.go | 1 + agent/client/workflow_startup_test.go | 1 + go.mod | 3 + go.sum | 2 + 18 files changed, 219 insertions(+), 38 deletions(-) create mode 100644 agent/client/default_listeners.go diff --git a/agent/client/client.go b/agent/client/client.go index ee1d53258d..97fd20fa98 100644 --- a/agent/client/client.go +++ b/agent/client/client.go @@ -2,18 +2,30 @@ package client import ( "context" + "errors" "fmt" + "io" + "log" "os" "strings" + "sync" "time" + retry "github.com/avast/retry-go" "github.com/kubeshop/tracetest/agent/proto" "google.golang.org/grpc" ) +const ( + ReconnectRetryAttempts = 6 + ReconnectRetryAttemptDelay = 1 * time.Second + defaultPingPeriod = 30 * time.Second +) + type Config struct { - APIKey string - AgentName string + APIKey string + AgentName string + PingPeriod time.Duration } type SessionConfig struct { @@ -22,6 +34,8 @@ type SessionConfig struct { } type Client struct { + mutex sync.Mutex + endpoint string conn *grpc.ClientConn config Config sessionConfig *SessionConfig @@ -69,7 +83,10 @@ func (c *Client) Start(ctx context.Context) error { return err } - c.startHearthBeat(ctx) + err = c.startHearthBeat(ctx) + if err != nil { + return err + } return nil } @@ -144,3 +161,49 @@ func (c *Client) getName() (string, error) { func isCancelledError(err error) bool { return err != nil && strings.Contains(err.Error(), "context canceled") } + +func (c *Client) reconnect() error { + // connection is not working. We need to reconnect + err := retry.Do(func() error { + return c.connect(context.Background()) + }, retry.Attempts(ReconnectRetryAttempts), retry.Delay(ReconnectRetryAttemptDelay)) + + if err != nil { + return fmt.Errorf("could not reconnect to server: %w", err) + } + + return c.Start(context.Background()) +} + +func (c *Client) handleDisconnectionError(inputErr error) (bool, error) { + if !isConnectionError(inputErr) { + // if it's nil or any error other than the one we care about, return it and let the caller handle it + return false, inputErr + } + + err := retry.Do(func() error { + return c.reconnect() + }) + + if err != nil { + log.Fatal(err) + } + + return true, nil +} + +func isConnectionError(err error) bool { + return err != nil && strings.Contains(err.Error(), "connection refused") +} + +func isEndOfFileError(err error) bool { + if err == nil { + return false + } + + if isEof := errors.Is(err, io.EOF); isEof { + return true + } + + return strings.Contains(err.Error(), "EOF") +} diff --git a/agent/client/connector.go b/agent/client/connector.go index 8e1f7cd6e3..0812f9a2a0 100644 --- a/agent/client/connector.go +++ b/agent/client/connector.go @@ -13,16 +13,28 @@ import ( ) func Connect(ctx context.Context, endpoint string, opts ...Option) (*Client, error) { - conn, err := connect(ctx, endpoint) - if err != nil { - return nil, err + config := Config{ + PingPeriod: defaultPingPeriod, + } + + client := &Client{ + endpoint: endpoint, + config: config, + triggerListener: triggerListener, + pollListener: pollListener, + shutdownListener: shutdownListener, + dataStoreConnectionListener: dataStoreConnectionListener, } - client := &Client{conn: conn} for _, opt := range opts { opt(client) } + err := client.connect(ctx) + if err != nil { + return nil, err + } + return client, nil } @@ -42,25 +54,30 @@ var retryPolicy = `{ }] }` -func connect(ctx context.Context, endpoint string) (*grpc.ClientConn, error) { +func (c *Client) connect(ctx context.Context) error { + c.mutex.Lock() + defer c.mutex.Unlock() + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() - transportCredentials, err := getTransportCredentialsForEndpoint(endpoint) + transportCredentials, err := getTransportCredentialsForEndpoint(c.endpoint) if err != nil { - return nil, fmt.Errorf("could not get transport credentials: %w", err) + return fmt.Errorf("could not get transport credentials: %w", err) } conn, err := grpc.DialContext( - ctx, endpoint, + ctx, c.endpoint, grpc.WithTransportCredentials(transportCredentials), grpc.WithDefaultServiceConfig(retryPolicy), + grpc.WithIdleTimeout(0), // disable grpc idle timeout ) if err != nil { - return nil, fmt.Errorf("could not connect to server: %w", err) + return fmt.Errorf("could not connect to server: %w", err) } - return conn, nil + c.conn = conn + return nil } func getTransportCredentialsForEndpoint(endpoint string) (credentials.TransportCredentials, error) { diff --git a/agent/client/default_listeners.go b/agent/client/default_listeners.go new file mode 100644 index 0000000000..9da2e9d99c --- /dev/null +++ b/agent/client/default_listeners.go @@ -0,0 +1,23 @@ +package client + +import ( + "context" + + "github.com/kubeshop/tracetest/agent/proto" +) + +func triggerListener(_ context.Context, _ *proto.TriggerRequest) error { + return nil +} + +func pollListener(_ context.Context, _ *proto.PollingRequest) error { + return nil +} + +func shutdownListener(_ context.Context, _ *proto.ShutdownRequest) error { + return nil +} + +func dataStoreConnectionListener(_ context.Context, _ *proto.DataStoreConnectionTestRequest) error { + return nil +} diff --git a/agent/client/mocks/grpc_server.go b/agent/client/mocks/grpc_server.go index 1b365908a8..cb13704494 100644 --- a/agent/client/mocks/grpc_server.go +++ b/agent/client/mocks/grpc_server.go @@ -7,6 +7,8 @@ import ( "net" "sync" + "github.com/avast/retry-go" + "github.com/kubeshop/tracetest/agent/client" "github.com/kubeshop/tracetest/agent/proto" "google.golang.org/grpc" ) @@ -21,6 +23,8 @@ type GrpcServerMock struct { lastTriggerResponse *proto.TriggerResponse lastPollingResponse *proto.PollingResponse + + server *grpc.Server } func NewGrpcServer() *GrpcServerMock { @@ -33,7 +37,12 @@ func NewGrpcServer() *GrpcServerMock { var wg sync.WaitGroup wg.Add(1) - go server.start(&wg) + err := retry.Do(func() error { + return server.start(&wg, 0) + }, retry.Attempts(client.ReconnectRetryAttempts), retry.Delay(client.ReconnectRetryAttemptDelay)) + if err != nil { + log.Fatal(err) + } wg.Wait() @@ -44,10 +53,10 @@ func (s *GrpcServerMock) Addr() string { return fmt.Sprintf("localhost:%d", s.port) } -func (s *GrpcServerMock) start(wg *sync.WaitGroup) { - lis, err := net.Listen("tcp", ":0") +func (s *GrpcServerMock) start(wg *sync.WaitGroup, port int) error { + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) if err != nil { - log.Fatalf("failed to listen: %v", err) + return fmt.Errorf("failed to listen: %w", err) } s.port = lis.Addr().(*net.TCPAddr).Port @@ -55,10 +64,17 @@ func (s *GrpcServerMock) start(wg *sync.WaitGroup) { server := grpc.NewServer() proto.RegisterOrchestratorServer(server, s) + s.server = server + wg.Done() - if err := server.Serve(lis); err != nil { - log.Fatalf("failed to serve: %v", err) - } + + go func() { + if err := server.Serve(lis); err != nil { + log.Fatal("failed to serve: %w", err) + } + }() + + return nil } func (s *GrpcServerMock) Connect(ctx context.Context, req *proto.ConnectRequest) (*proto.AgentConfiguration, error) { @@ -166,3 +182,7 @@ func (s *GrpcServerMock) TerminateConnection(reason string) { Reason: reason, } } + +func (s *GrpcServerMock) Stop() { + s.server.Stop() +} diff --git a/agent/client/options.go b/agent/client/options.go index 4f47f0e9ff..d5f71a6b45 100644 --- a/agent/client/options.go +++ b/agent/client/options.go @@ -1,5 +1,7 @@ package client +import "time" + type Option func(*Client) func WithAPIKey(apiKey string) Option { @@ -13,3 +15,9 @@ func WithAgentName(name string) Option { c.config.AgentName = name } } + +func WithPingPeriod(period time.Duration) Option { + return func(c *Client) { + c.config.PingPeriod = period + } +} diff --git a/agent/client/workflow_listen_for_ds_connection_tests.go b/agent/client/workflow_listen_for_ds_connection_tests.go index 2ef2f84ba9..d7d91545a0 100644 --- a/agent/client/workflow_listen_for_ds_connection_tests.go +++ b/agent/client/workflow_listen_for_ds_connection_tests.go @@ -2,10 +2,9 @@ package client import ( "context" - "errors" "fmt" - "io" "log" + "time" "github.com/kubeshop/tracetest/agent/proto" ) @@ -22,12 +21,19 @@ func (c *Client) startDataStoreConnectionTestListener(ctx context.Context) error for { req := proto.DataStoreConnectionTestRequest{} err := stream.RecvMsg(&req) - if errors.Is(err, io.EOF) || isCancelledError(err) { + if isEndOfFileError(err) || isCancelledError(err) { + return + } + + reconnected, err := c.handleDisconnectionError(err) + if reconnected { return } if err != nil { - log.Fatal("could not get message from ds connection stream: %w", err) + log.Println("could not get message from data store connection stream: %w", err) + time.Sleep(1 * time.Second) + continue } // TODO: Get ctx from request diff --git a/agent/client/workflow_listen_for_poll_requests.go b/agent/client/workflow_listen_for_poll_requests.go index 34d3e50e2b..dee9eae065 100644 --- a/agent/client/workflow_listen_for_poll_requests.go +++ b/agent/client/workflow_listen_for_poll_requests.go @@ -2,10 +2,9 @@ package client import ( "context" - "errors" "fmt" - "io" "log" + "time" "github.com/kubeshop/tracetest/agent/proto" ) @@ -22,12 +21,19 @@ func (c *Client) startPollerListener(ctx context.Context) error { for { resp := proto.PollingRequest{} err := stream.RecvMsg(&resp) - if errors.Is(err, io.EOF) || isCancelledError(err) { + if isEndOfFileError(err) || isCancelledError(err) { + return + } + + reconnected, err := c.handleDisconnectionError(err) + if reconnected { return } if err != nil { - log.Fatal("could not get message from polling stream: %w", err) + log.Println("could not get message from poller stream: %w", err) + time.Sleep(1 * time.Second) + continue } // TODO: Get ctx from request diff --git a/agent/client/workflow_listen_for_poll_requests_test.go b/agent/client/workflow_listen_for_poll_requests_test.go index d622c02f74..2019dab411 100644 --- a/agent/client/workflow_listen_for_poll_requests_test.go +++ b/agent/client/workflow_listen_for_poll_requests_test.go @@ -14,6 +14,7 @@ import ( func TestPollWorkflow(t *testing.T) { server := mocks.NewGrpcServer() + defer server.Stop() client, err := client.Connect(context.Background(), server.Addr()) require.NoError(t, err) diff --git a/agent/client/workflow_listen_for_trigger_requests.go b/agent/client/workflow_listen_for_trigger_requests.go index c66f7a0a6b..ade503c227 100644 --- a/agent/client/workflow_listen_for_trigger_requests.go +++ b/agent/client/workflow_listen_for_trigger_requests.go @@ -2,10 +2,9 @@ package client import ( "context" - "errors" "fmt" - "io" "log" + "time" "github.com/kubeshop/tracetest/agent/proto" ) @@ -22,12 +21,19 @@ func (c *Client) startTriggerListener(ctx context.Context) error { for { resp := proto.TriggerRequest{} err := stream.RecvMsg(&resp) - if errors.Is(err, io.EOF) || isCancelledError(err) { + if isEndOfFileError(err) || isCancelledError(err) { + return + } + + reconnected, err := c.handleDisconnectionError(err) + if reconnected { return } if err != nil { - log.Fatal("could not get message from trigger stream: %w", err) + log.Println("could not get message from trigger stream: %w", err) + time.Sleep(1 * time.Second) + continue } // TODO: get context from request diff --git a/agent/client/workflow_listen_for_trigger_requests_test.go b/agent/client/workflow_listen_for_trigger_requests_test.go index 2e228cf2e5..082f29bea6 100644 --- a/agent/client/workflow_listen_for_trigger_requests_test.go +++ b/agent/client/workflow_listen_for_trigger_requests_test.go @@ -14,6 +14,7 @@ import ( func TestTriggerWorkflow(t *testing.T) { server := mocks.NewGrpcServer() + defer server.Stop() client, err := client.Connect(context.Background(), server.Addr()) require.NoError(t, err) diff --git a/agent/client/workflow_ping.go b/agent/client/workflow_ping.go index 3380bb3236..1e7d8ad993 100644 --- a/agent/client/workflow_ping.go +++ b/agent/client/workflow_ping.go @@ -2,6 +2,7 @@ package client import ( "context" + "log" "time" "github.com/kubeshop/tracetest/agent/proto" @@ -9,11 +10,25 @@ import ( func (c *Client) startHearthBeat(ctx context.Context) error { client := proto.NewOrchestratorClient(c.conn) - ticker := time.NewTicker(2 * time.Minute) + ticker := time.NewTicker(c.config.PingPeriod) go func() { for range ticker.C { - client.Ping(ctx, c.sessionConfig.AgentIdentification) + _, err := client.Ping(ctx, c.sessionConfig.AgentIdentification) + if isEndOfFileError(err) || isCancelledError(err) { + return + } + + reconnected, err := c.handleDisconnectionError(err) + if reconnected { + return + } + + if err != nil { + log.Println("could not get message from ping stream: %w", err) + time.Sleep(1 * time.Second) + continue + } } }() diff --git a/agent/client/workflow_send_trace_test.go b/agent/client/workflow_send_trace_test.go index 954081977c..9c396fffa8 100644 --- a/agent/client/workflow_send_trace_test.go +++ b/agent/client/workflow_send_trace_test.go @@ -13,6 +13,7 @@ import ( func TestSendTrace(t *testing.T) { server := mocks.NewGrpcServer() + defer server.Stop() client, err := client.Connect(context.Background(), server.Addr()) require.NoError(t, err) diff --git a/agent/client/workflow_send_trigger_response_test.go b/agent/client/workflow_send_trigger_response_test.go index 0ed63a535e..4581ce529c 100644 --- a/agent/client/workflow_send_trigger_response_test.go +++ b/agent/client/workflow_send_trigger_response_test.go @@ -13,6 +13,7 @@ import ( func TestSendTriggerResult(t *testing.T) { server := mocks.NewGrpcServer() + defer server.Stop() client, err := client.Connect(context.Background(), server.Addr()) require.NoError(t, err) diff --git a/agent/client/workflow_shutdown.go b/agent/client/workflow_shutdown.go index 04f6448d9d..a25c6d39e2 100644 --- a/agent/client/workflow_shutdown.go +++ b/agent/client/workflow_shutdown.go @@ -2,10 +2,9 @@ package client import ( "context" - "errors" "fmt" - "io" "log" + "time" "github.com/kubeshop/tracetest/agent/proto" ) @@ -23,12 +22,19 @@ func (c *Client) startShutdownListener(ctx context.Context) error { resp := proto.ShutdownRequest{} err := stream.RecvMsg(&resp) - if errors.Is(err, io.EOF) || isCancelledError(err) { + if isEndOfFileError(err) || isCancelledError(err) { + return + } + + reconnected, err := c.handleDisconnectionError(err) + if reconnected { return } if err != nil { - log.Fatal("could not get shutdown listener: %w", err) + log.Println("could not get message from shutdown stream: %w", err) + time.Sleep(1 * time.Second) + continue } // TODO: get context from request diff --git a/agent/client/workflow_shutdown_test.go b/agent/client/workflow_shutdown_test.go index 6d03135264..60666efb95 100644 --- a/agent/client/workflow_shutdown_test.go +++ b/agent/client/workflow_shutdown_test.go @@ -14,6 +14,7 @@ import ( func TestShutdownFlow(t *testing.T) { server := mocks.NewGrpcServer() + defer server.Stop() client, err := client.Connect(context.Background(), server.Addr()) require.NoError(t, err) diff --git a/agent/client/workflow_startup_test.go b/agent/client/workflow_startup_test.go index 4e16123f2e..3fcc645c72 100644 --- a/agent/client/workflow_startup_test.go +++ b/agent/client/workflow_startup_test.go @@ -13,6 +13,7 @@ import ( func TestStartupFlow(t *testing.T) { server := mocks.NewGrpcServer() + defer server.Stop() client, err := client.Connect(context.Background(), server.Addr()) require.NoError(t, err) diff --git a/go.mod b/go.mod index 62b9cfd2b4..aea54216aa 100644 --- a/go.mod +++ b/go.mod @@ -96,6 +96,8 @@ require ( github.com/Microsoft/go-winio v0.5.2 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/Shopify/toxiproxy v2.1.4+incompatible // indirect + github.com/avast/retry-go v3.0.0+incompatible // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/containerd/console v1.0.3 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect @@ -196,6 +198,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect ) // Temporary fix until we manage to merge the patch to the gnomock repo (https://github.com/orlangure/gnomock/pull/534) diff --git a/go.sum b/go.sum index 83094c6260..20dd4075e6 100644 --- a/go.sum +++ b/go.sum @@ -243,6 +243,8 @@ github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:o github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= +github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= +github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= From f41faa67f90660fc5d3d91e5d1761d701cc52b98 Mon Sep 17 00:00:00 2001 From: Daniel Baptista Dias Date: Fri, 10 Nov 2023 14:55:24 -0300 Subject: [PATCH 17/19] fix: convert zipCode as string for HTTP tests on OTel Demo (#3344) --- web/src/constants/Demo.constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/constants/Demo.constants.ts b/web/src/constants/Demo.constants.ts index fa16db8037..5c7749b355 100644 --- a/web/src/constants/Demo.constants.ts +++ b/web/src/constants/Demo.constants.ts @@ -187,7 +187,7 @@ export function getOtelDemo(demoSettings: Demo) { state: 'CA', country: 'United States', city: 'Mountain View', - zipCode: 94043, + zipCode: '94043', }, userCurrency: 'USD', creditCard: { From 5d509a17dbbb3fe20cbf75724b7121ec882c9f72 Mon Sep 17 00:00:00 2001 From: Oscar Reyes Date: Fri, 10 Nov 2023 13:00:59 -0600 Subject: [PATCH 18/19] fix(backend): Adding Composed Primary Keys (#3345) * fix(backend): Adding Composed Primary Keys * fix: fixing repos and migrations --- .../migrations/34_add_composite_pkey.down.sql | 117 ++++++++++++++++++ .../migrations/34_add_composite_pkey.up.sql | 117 ++++++++++++++++++ server/test/run_repository.go | 13 +- server/test/test_repository.go | 18 ++- server/testsuite/testsuite_repository.go | 18 ++- server/testsuite/testsuite_run_repository.go | 15 +-- server/variableset/variableset_repository.go | 8 +- 7 files changed, 266 insertions(+), 40 deletions(-) create mode 100644 server/migrations/34_add_composite_pkey.down.sql create mode 100644 server/migrations/34_add_composite_pkey.up.sql diff --git a/server/migrations/34_add_composite_pkey.down.sql b/server/migrations/34_add_composite_pkey.down.sql new file mode 100644 index 0000000000..4474480193 --- /dev/null +++ b/server/migrations/34_add_composite_pkey.down.sql @@ -0,0 +1,117 @@ +BEGIN; + +-- Tests +ALTER TABLE + tests DROP CONSTRAINT tests_pkey CASCADE, +ADD + CONSTRAINT tests_pkey PRIMARY KEY (id, version), +ALTER COLUMN + tenant_id DROP DEFAULT, +ALTER COLUMN + tenant_id DROP NOT NULL; + +UPDATE + tests +SET + tenant_id = null +WHERE + tenant_id = ''; + +ALTER TABLE + tests +ALTER COLUMN + tenant_id TYPE uuid using tenant_id :: uuid; + +-- # Test Runs +ALTER TABLE + test_runs DROP CONSTRAINT test_runs_pkey CASCADE, +ADD + CONSTRAINT test_runs_pkey PRIMARY KEY (id, test_id), +ADD + CONSTRAINT fk_test_runs_tests FOREIGN KEY (test_id, test_version) REFERENCES tests(id, version), +ALTER COLUMN + tenant_id DROP DEFAULT, +ALTER COLUMN + tenant_id DROP NOT NULL; + +UPDATE + test_runs +SET + tenant_id = null +WHERE + tenant_id = ''; + +ALTER TABLE + test_runs +ALTER COLUMN + tenant_id TYPE uuid using tenant_id :: uuid; + +-- Test Suites +ALTER TABLE + test_suites DROP CONSTRAINT transaction_pkey CASCADE, +ADD + CONSTRAINT transaction_pkey PRIMARY KEY (id, version), +ALTER COLUMN + tenant_id DROP DEFAULT, +ALTER COLUMN + tenant_id DROP NOT NULL; + +UPDATE + test_suites +SET + tenant_id = null +WHERE + tenant_id = ''; + +ALTER TABLE + test_suites +ALTER COLUMN + tenant_id TYPE uuid using tenant_id :: uuid; + +-- Test Suite Runs +ALTER TABLE + test_suite_runs DROP CONSTRAINT transaction_run_pkey CASCADE, +ADD + CONSTRAINT transaction_run_pkey PRIMARY KEY (id, test_suite_id), +ADD + CONSTRAINT transaction_run_transactions_fk FOREIGN KEY (test_suite_id, test_suite_version) REFERENCES test_suites(id, version), +ALTER COLUMN + tenant_id DROP DEFAULT, +ALTER COLUMN + tenant_id DROP NOT NULL; + +UPDATE + test_suite_runs +SET + tenant_id = null +WHERE + tenant_id = ''; + +ALTER TABLE + test_suite_runs +ALTER COLUMN + tenant_id TYPE uuid using tenant_id :: uuid; + +-- Variable Sets +ALTER TABLE + variable_sets DROP CONSTRAINT environments_pkey CASCADE, +ADD + CONSTRAINT environments_pkey PRIMARY KEY (id), +ALTER COLUMN + tenant_id DROP DEFAULT, +ALTER COLUMN + tenant_id DROP NOT NULL; + +UPDATE + variable_sets +SET + tenant_id = null +WHERE + tenant_id = ''; + +ALTER TABLE + variable_sets +ALTER COLUMN + tenant_id TYPE uuid using tenant_id :: uuid; + +COMMIT; \ No newline at end of file diff --git a/server/migrations/34_add_composite_pkey.up.sql b/server/migrations/34_add_composite_pkey.up.sql new file mode 100644 index 0000000000..6388dcaa49 --- /dev/null +++ b/server/migrations/34_add_composite_pkey.up.sql @@ -0,0 +1,117 @@ +BEGIN; + +-- Tests +ALTER TABLE + tests +ALTER COLUMN + tenant_id TYPE varchar; + +UPDATE + tests +SET + tenant_id = '' +WHERE + tenant_id is null; + +ALTER TABLE + tests DROP CONSTRAINT tests_pkey CASCADE, +ADD + CONSTRAINT tests_pkey PRIMARY KEY (id, version, tenant_id), +ALTER COLUMN + tenant_id +SET + DEFAULT ''; + +-- Test Runs +ALTER TABLE + test_runs +ALTER COLUMN + tenant_id TYPE varchar; + +UPDATE + test_runs +SET + tenant_id = '' +WHERE + tenant_id is null; + +ALTER TABLE + test_runs DROP CONSTRAINT test_runs_pkey CASCADE, +ADD + CONSTRAINT test_runs_pkey PRIMARY KEY (id, test_id, tenant_id), +ADD + CONSTRAINT fk_test_runs_tests FOREIGN KEY (test_id, test_version, tenant_id) REFERENCES tests(id, version, tenant_id), +ALTER COLUMN + tenant_id +SET + DEFAULT ''; + +-- Test Suites +ALTER TABLE + test_suites +ALTER COLUMN + tenant_id TYPE varchar; + +UPDATE + test_suites +SET + tenant_id = '' +WHERE + tenant_id is null; + +ALTER TABLE + test_suites DROP CONSTRAINT transaction_pkey CASCADE, +ADD + CONSTRAINT transaction_pkey PRIMARY KEY (id, version, tenant_id), +ALTER COLUMN + tenant_id +SET + DEFAULT ''; + +-- Test Suite Runs +ALTER TABLE + test_suite_runs +ALTER COLUMN + tenant_id TYPE varchar; + +UPDATE + test_suite_runs +SET + tenant_id = '' +WHERE + tenant_id is null; + +ALTER TABLE + test_suite_runs DROP CONSTRAINT transaction_run_pkey CASCADE, +ADD + CONSTRAINT transaction_run_pkey PRIMARY KEY (id, test_suite_id, tenant_id), +ADD + CONSTRAINT transaction_run_transactions_fk FOREIGN KEY (test_suite_id, test_suite_version, tenant_id) REFERENCES test_suites(id, version, tenant_id), +ALTER COLUMN + tenant_id +SET + DEFAULT ''; + +-- Variable Sets +ALTER TABLE + variable_sets +ALTER COLUMN + tenant_id TYPE varchar; + +UPDATE + variable_sets +SET + tenant_id = '' +WHERE + tenant_id is null; + +ALTER TABLE + variable_sets DROP CONSTRAINT environments_pkey CASCADE, +ADD + CONSTRAINT environments_pkey PRIMARY KEY (id, tenant_id), +ALTER COLUMN + tenant_id +SET + DEFAULT ''; + +COMMIT; \ No newline at end of file diff --git a/server/test/run_repository.go b/server/test/run_repository.go index 6390a69f42..63433a8c68 100644 --- a/server/test/run_repository.go +++ b/server/test/run_repository.go @@ -172,12 +172,7 @@ func (r *runRepository) CreateRun(ctx context.Context, test Test, run Run) (Run, return Run{}, fmt.Errorf("sql exec: %w", err) } - tenantID := sqlutil.TenantID(ctx) - - var runID int - err = tx.QueryRowContext( - ctx, - replaceRunSequenceName(createRunQuery, test.ID), + params := sqlutil.TenantInsert(ctx, test.ID, test.SafeVersion(), run.CreatedAt, @@ -194,8 +189,10 @@ func (r *runRepository) CreateRun(ctx context.Context, test Test, run Run) (Run, jsonVariableSet, jsonlinter, jsonGatesResult, - tenantID, - ).Scan(&runID) + ) + + var runID int + err = tx.QueryRowContext(ctx, replaceRunSequenceName(createRunQuery, test.ID), params...).Scan(&runID) if err != nil { tx.Rollback() return Run{}, fmt.Errorf("sql exec: %w", err) diff --git a/server/test/test_repository.go b/server/test/test_repository.go index 73f9c1ac36..f82c2d1a2a 100644 --- a/server/test/test_repository.go +++ b/server/test/test_repository.go @@ -74,14 +74,14 @@ const ( t.specs, t.outputs, t.created_at, - (SELECT COUNT(*) FROM test_runs tr WHERE tr.test_id = t.id) as total_runs, + (SELECT COUNT(*) FROM test_runs tr WHERE tr.test_id = t.id AND tr.tenant_id = t.tenant_id) as total_runs, last_test_run.created_at as last_test_run_time, last_test_run.pass as last_test_run_pass, last_test_run.fail as last_test_run_fail FROM tests t LEFT OUTER JOIN ( - SELECT MAX(id) as id, test_id FROM test_runs GROUP BY test_id - ) as ltr ON ltr.test_id = t.id + SELECT MAX(id) as id, test_id, tenant_id FROM test_runs GROUP BY test_id, tenant_id + ) as ltr ON ltr.test_id = t.id AND ltr.tenant_id = t.tenant_id LEFT OUTER JOIN test_runs last_test_run ON last_test_run.test_id = ltr.test_id AND last_test_run.id = ltr.id @@ -89,8 +89,8 @@ const ( testMaxVersionQuery = ` INNER JOIN ( - SELECT id as idx, max(version) as latest_version FROM tests GROUP BY idx - ) as latest_tests ON latest_tests.idx = t.id AND t.version = latest_tests.latest_version + SELECT id as idx, tenant_id, max(version) as latest_version FROM tests GROUP BY idx, tenant_id + ) as latest_tests ON latest_tests.idx = t.id AND t.version = latest_tests.latest_version AND t.tenant_id = latest_tests.tenant_id ` ) @@ -380,10 +380,7 @@ func (r *repository) insertTest(ctx context.Context, test Test) (Test, error) { return Test{}, fmt.Errorf("encoding error: %w", err) } - tenantID := sqlutil.TenantID(ctx) - - _, err = stmt.ExecContext( - ctx, + params := sqlutil.TenantInsert(ctx, test.ID, test.Version, test.Name, @@ -392,8 +389,9 @@ func (r *repository) insertTest(ctx context.Context, test Test) (Test, error) { specsJson, outputsJson, test.CreatedAt, - tenantID, ) + + _, err = stmt.ExecContext(ctx, params...) if err != nil { return Test{}, fmt.Errorf("sql exec: %w", err) } diff --git a/server/testsuite/testsuite_repository.go b/server/testsuite/testsuite_repository.go index c56ffdeda0..2405764464 100644 --- a/server/testsuite/testsuite_repository.go +++ b/server/testsuite/testsuite_repository.go @@ -162,8 +162,8 @@ const getTestSuiteSQL = ` %s FROM test_suites t LEFT OUTER JOIN ( - SELECT MAX(id) as id, test_suite_id FROM test_suite_runs GROUP BY test_suite_id - ) as ltr ON ltr.test_suite_id = t.id + SELECT MAX(id) as id, tenant_id, test_suite_id FROM test_suite_runs GROUP BY test_suite_id, tenant_id + ) as ltr ON ltr.test_suite_id = t.id AND ltr.tenant_id = t.tenant_id LEFT OUTER JOIN test_suite_runs last_test_suite_run ON last_test_suite_run.test_suite_id = ltr.test_suite_id AND last_test_suite_run.id = ltr.id @@ -171,8 +171,8 @@ const getTestSuiteSQL = ` const testSuiteMaxVersionQuery = ` INNER JOIN ( - SELECT id as idx, max(version) as latest_version FROM test_suites GROUP BY idx - ) as latest_test_suites ON latest_test_suites.idx = t.id + SELECT id as idx, tenant_id, max(version) as latest_version FROM test_suites GROUP BY idx, tenant_id + ) as latest_test_suites ON latest_test_suites.idx = t.id AND latest_test_suites.tenant_id = t.tenant_id WHERE t.version = latest_test_suites.latest_version ` @@ -241,7 +241,7 @@ func querySelect() string { HAVING ts.test_suite_id = t.id AND ts.test_suite_version = t.version ) as step_ids_query ) as step_ids, - (SELECT COUNT(*) FROM test_suite_runs tr WHERE tr.test_suite_id = t.id) as total_runs, + (SELECT COUNT(*) FROM test_suite_runs tr WHERE tr.test_suite_id = t.id AND tr.tenant_id = t.tenant_id) as total_runs, last_test_suite_run.created_at as last_test_suite_run_time, last_test_suite_run.pass as last_test_run_pass, last_test_suite_run.fail as last_test_run_fail @@ -353,17 +353,15 @@ func (r *Repository) insertIntoTestSuites(ctx context.Context, suite TestSuite) } defer stmt.Close() - tenantID := sqlutil.TenantID(ctx) - - _, err = stmt.ExecContext( - ctx, + params := sqlutil.TenantInsert(ctx, suite.ID, suite.GetVersion(), suite.Name, suite.Description, suite.GetCreatedAt(), - tenantID, ) + + _, err = stmt.ExecContext(ctx, params...) if err != nil { return TestSuite{}, fmt.Errorf("sql exec: %w", err) } diff --git a/server/testsuite/testsuite_run_repository.go b/server/testsuite/testsuite_run_repository.go index 40a19d2b26..05f0195512 100644 --- a/server/testsuite/testsuite_run_repository.go +++ b/server/testsuite/testsuite_run_repository.go @@ -124,12 +124,7 @@ func (td *RunRepository) CreateRun(ctx context.Context, tr TestSuiteRun) (TestSu return TestSuiteRun{}, fmt.Errorf("sql exec: %w", err) } - tenantID := sqlutil.TenantID(ctx) - - var runID int - err = tx.QueryRowContext( - ctx, - replaceTestSuiteRunSequenceName(createTestSuiteRunQuery, tr.TestSuiteID), + params := sqlutil.TenantInsert(ctx, tr.TestSuiteID, tr.TestSuiteVersion, tr.CreatedAt, @@ -137,7 +132,13 @@ func (td *RunRepository) CreateRun(ctx context.Context, tr TestSuiteRun) (TestSu tr.CurrentTest, jsonMetadata, jsonVariableSet, - tenantID, + ) + + var runID int + err = tx.QueryRowContext( + ctx, + replaceTestSuiteRunSequenceName(createTestSuiteRunQuery, tr.TestSuiteID), + params..., ).Scan(&runID) if err != nil { tx.Rollback() diff --git a/server/variableset/variableset_repository.go b/server/variableset/variableset_repository.go index d2380dd2e7..88f542c02f 100644 --- a/server/variableset/variableset_repository.go +++ b/server/variableset/variableset_repository.go @@ -259,18 +259,16 @@ func (r *Repository) insertIntoEnvironments(ctx context.Context, variableSet Var return VariableSet{}, fmt.Errorf("encoding error: %w", err) } - tenantID := sqlutil.TenantID(ctx) - - _, err = stmt.ExecContext( - ctx, + params := sqlutil.TenantInsert(ctx, variableSet.ID, variableSet.Name, variableSet.Description, variableSet.CreatedAt, jsonValues, - tenantID, ) + _, err = stmt.ExecContext(ctx, params...) + if err != nil { return VariableSet{}, fmt.Errorf("sql exec: %w", err) } From 33783c4959d9c4dc1db160fc4e91d891203164e6 Mon Sep 17 00:00:00 2001 From: Daniel Baptista Dias Date: Mon, 13 Nov 2023 13:52:31 -0300 Subject: [PATCH 19/19] chore: add example with pokeshop and tracetest agent (#3343) --- .../tracetest-agent-with-pokeshop/README.md | 11 + .../docker-compose.yaml | 206 ++++++++++++++++++ 2 files changed, 217 insertions(+) create mode 100644 examples/tracetest-agent-with-pokeshop/README.md create mode 100644 examples/tracetest-agent-with-pokeshop/docker-compose.yaml diff --git a/examples/tracetest-agent-with-pokeshop/README.md b/examples/tracetest-agent-with-pokeshop/README.md new file mode 100644 index 0000000000..b5fbd01f5b --- /dev/null +++ b/examples/tracetest-agent-with-pokeshop/README.md @@ -0,0 +1,11 @@ +# Tracetest Agent with Pokeshop + +This example shows how you can use [Tracetest agent](https://docs.tracetest.io/concepts/agent) to capture telemetry data locally and run tests on `app.tracetest.io`. + +Note that the environment variable `COLLECTOR_ENDPOINT` is pointing to Tracetest Agent OTLP endpoint, sending all telemetry data directly to it. + +To run this example, just set you Environment API key as the env var `TRACETEST_API_KEY` and run: + +```sh +TRACETEST_API_KEY=my-api-key docker compose up +``` diff --git a/examples/tracetest-agent-with-pokeshop/docker-compose.yaml b/examples/tracetest-agent-with-pokeshop/docker-compose.yaml new file mode 100644 index 0000000000..8ff289e600 --- /dev/null +++ b/examples/tracetest-agent-with-pokeshop/docker-compose.yaml @@ -0,0 +1,206 @@ +name: tracetest +services: + cache: + healthcheck: + test: + - CMD + - redis-cli + - ping + timeout: 3s + interval: 1s + retries: 60 + image: redis:6 + networks: + default: null + restart: unless-stopped + demo-api: + depends_on: + cache: + condition: service_healthy + required: true + postgres: + condition: service_healthy + required: true + queue: + condition: service_healthy + required: true + environment: + COLLECTOR_ENDPOINT: http://tracetest-agent:4317 + DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres?schema=public + NPM_RUN_COMMAND: api + POKE_API_BASE_URL: https://pokeapi.co/api/v2 + RABBITMQ_HOST: queue + REDIS_URL: cache + healthcheck: + test: + - CMD + - wget + - --spider + - localhost:8081 + timeout: 3s + interval: 1s + retries: 60 + image: kubeshop/demo-pokemon-api:latest + networks: + default: null + ports: + - mode: ingress + target: 8081 + published: 8081 + protocol: tcp + pull_policy: always + restart: unless-stopped + demo-rpc: + depends_on: + cache: + condition: service_healthy + required: true + postgres: + condition: service_healthy + required: true + queue: + condition: service_healthy + required: true + environment: + COLLECTOR_ENDPOINT: http://tracetest-agent:4317 + DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres?schema=public + NPM_RUN_COMMAND: rpc + POKE_API_BASE_URL: https://pokeapi.co/api/v2 + RABBITMQ_HOST: queue + REDIS_URL: cache + healthcheck: + test: + - CMD + - lsof + - -i + - "8082" + timeout: 3s + interval: 1s + retries: 60 + image: kubeshop/demo-pokemon-api:latest + networks: + default: null + ports: + - mode: ingress + target: 8082 + published: 8082 + protocol: tcp + pull_policy: always + restart: unless-stopped + demo-streaming-worker: + depends_on: + cache: + condition: service_healthy + required: true + postgres: + condition: service_healthy + required: true + stream: + condition: service_healthy + required: true + environment: + COLLECTOR_ENDPOINT: http://tracetest-agent:4317 + DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres?schema=public + KAFKA_BROKER: stream:9092 + KAFKA_CLIENT_ID: streaming-worker + KAFKA_TOPIC: pokemon + NPM_RUN_COMMAND: stream-worker + POKE_API_BASE_URL: https://pokeapi.co/api/v2 + REDIS_URL: cache + ZIPKIN_URL: http://localhost:9411 + image: kubeshop/demo-pokemon-api:latest + networks: + default: null + demo-worker: + depends_on: + cache: + condition: service_healthy + required: true + postgres: + condition: service_healthy + required: true + queue: + condition: service_healthy + required: true + environment: + COLLECTOR_ENDPOINT: http://tracetest-agent:4317 + DATABASE_URL: postgresql://postgres:postgres@postgres:5432/postgres?schema=public + NPM_RUN_COMMAND: worker + POKE_API_BASE_URL: https://pokeapi.co/api/v2 + RABBITMQ_HOST: queue + REDIS_URL: cache + image: kubeshop/demo-pokemon-api:latest + networks: + default: null + pull_policy: always + restart: unless-stopped + postgres: + environment: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + healthcheck: + test: + - CMD-SHELL + - pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB" + timeout: 5s + interval: 1s + retries: 60 + image: postgres:14 + networks: + default: null + queue: + healthcheck: + test: + - CMD-SHELL + - rabbitmq-diagnostics -q check_running + timeout: 5s + interval: 1s + retries: 60 + image: rabbitmq:3.8-management + networks: + default: null + restart: unless-stopped + stream: + environment: + CLUSTER_ID: ckjPoprWQzOf0-FuNkGfFQ + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://stream:9092,PLAINTEXT_HOST://127.0.0.1:29092 + KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true" + KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER + KAFKA_CONTROLLER_QUORUM_VOTERS: 1@0.0.0.0:9093 + KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: "0" + KAFKA_HEAP_OPTS: -Xmx200m -Xms200m + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT + KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093,PLAINTEXT_HOST://:29092 + KAFKA_METADATA_LOG_MAX_RECORD_BYTES_BETWEEN_SNAPSHOTS: "2800" + KAFKA_METADATA_LOG_SEGMENT_MS: "15000" + KAFKA_METADATA_MAX_RETENTION_MS: "60000" + KAFKA_NODE_ID: "1" + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1" + KAFKA_PROCESS_ROLES: controller,broker + KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: "1" + healthcheck: + test: + - CMD-SHELL + - nc -z stream 9092 + timeout: 10s + interval: 5s + retries: 10 + start_period: 10s + image: confluentinc/cp-kafka:latest-ubi8 + networks: + default: null + ports: + - mode: ingress + target: 29092 + published: 29092 + protocol: tcp + tracetest-agent: + environment: + TRACETEST_DEV: ${TRACETEST_DEV} + TRACETEST_API_KEY: ${TRACETEST_API_KEY} + image: kubeshop/tracetest-agent:latest + networks: + default: null +networks: + default: + name: tracetest_default