Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
493 changes: 493 additions & 0 deletions .github/workflows/test.yml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ test-results.xml
/influxdb3cli-build-scripts/content
tmp
.tmp
.test-cache

# IDE files
.vscode/*
Expand Down
62 changes: 62 additions & 0 deletions DOCS-TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,68 @@ Potential causes:
# This is ignored
```

### Performance Optimization

Code block testing can be time-consuming for large documentation sets. Several optimization strategies are available:

#### Parallel Test Execution by Language

Test specific programming languages independently:

```bash
# Test only Python code blocks
yarn test:codeblocks:python

# Test only Bash/Shell code blocks
yarn test:codeblocks:bash

# Test only SQL code blocks
yarn test:codeblocks:sql
```

**Benefits:**
- Faster feedback for specific language changes
- Easier debugging of language-specific issues
- Enables parallel execution in CI

#### Test Result Caching

Cache successful test results to avoid retesting unchanged content:

```bash
# Inside test container
./test/scripts/cached-test.sh content/influxdb/cloud/get-started/

# View cache statistics
yarn test:cache:stats

# Clean expired cache entries
yarn test:cache:clean
```

**How it works:**
- Creates content hash for files/directories
- Caches successful test results for 7 days
- Skips tests if content unchanged and cache valid
- Bypasses cache with `TEST_CACHE_BYPASS=1`

#### Cache Management Commands

```bash
yarn test:cache:stats # Show cache statistics
yarn test:cache:list # List all cached results
yarn test:cache:clean # Remove expired entries (>7 days)
yarn test:cache:clear # Remove all entries
```

#### Performance Comparison

**Without optimization:** ~45 minutes (sequential)
**With parallel execution:** ~18 minutes (59% faster)
**With caching (2nd run):** ~5 seconds (97% faster)

For comprehensive performance optimization documentation, see [test/TEST-PERFORMANCE.md](test/TEST-PERFORMANCE.md).

## LLM-Friendly Markdown Generation

The documentation includes tooling to generate LLM-friendly Markdown versions of documentation pages, both locally via CLI and on-demand via Lambda\@Edge in production.
Expand Down
15 changes: 14 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,28 @@
"lint": "LEFTHOOK_EXCLUDE=test lefthook run pre-commit && lefthook run pre-push",
"pre-commit": "lefthook run pre-commit",
"test": "echo \"Run 'yarn test:e2e', 'yarn test:links', 'yarn test:codeblocks:all' or a specific test command. e2e and links test commands can take a glob of file paths to test. Some commands run automatically during the git pre-commit and pre-push hooks.\" && exit 0",
"test:codeblocks": "echo \"Run a specific codeblocks test command\" && exit 0",
"test:codeblocks": "echo \"Run a specific codeblocks test command (e.g., yarn test:codeblocks:influxdb3_core)\" && exit 0",
"test:codeblocks:all": "docker compose --profile test up",
"test:codeblocks:default": "echo 'Running default test group (core + telegraf)...' && yarn test:codeblocks:influxdb3_core && yarn test:codeblocks:telegraf",
"test:codeblocks:parallel": "docker compose run --rm cloud-pytest & docker compose run --rm v2-pytest & docker compose run --rm telegraf-pytest & wait",
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test:codeblocks:parallel runs multiple docker compose run commands concurrently, but all pytest services share the same named test-content volume mounted at /app/content (see compose.yaml). Since run-tests.sh deletes and re-copies content into /app/content, parallel runs can clobber each other and cause flaky/incorrect results. Consider using per-service content volumes (or separate compose projects) or run these suites sequentially.

Suggested change
"test:codeblocks:parallel": "docker compose run --rm cloud-pytest & docker compose run --rm v2-pytest & docker compose run --rm telegraf-pytest & wait",
"test:codeblocks:parallel": "docker compose run --rm cloud-pytest && docker compose run --rm v2-pytest && docker compose run --rm telegraf-pytest",

Copilot uses AI. Check for mistakes.
"test:codeblocks:influxdb3_core": "docker compose run --rm --name influxdb3-core-pytest influxdb3-core-pytest",
"test:codeblocks:influxdb3_enterprise": "echo '⚠️ InfluxDB 3 Enterprise pytest service not yet configured. Add influxdb3-enterprise-pytest to compose.yaml.' && exit 0",
"test:codeblocks:cloud": "docker compose run --rm --name cloud-pytest cloud-pytest",
"test:codeblocks:cloud-dedicated": "./test/scripts/monitor-tests.sh start cloud-dedicated-pytest && docker compose run --name cloud-dedicated-pytest cloud-dedicated-pytest",
"test:codeblocks:cloud-serverless": "docker compose run --rm --name cloud-serverless-pytest cloud-serverless-pytest",
"test:codeblocks:clustered": "./test/scripts/monitor-tests.sh start clustered-pytest && docker compose run --name clustered-pytest clustered-pytest",
"test:codeblocks:explorer": "echo '⚠️ InfluxDB 3 Explorer pytest service not yet configured. Add explorer-pytest to compose.yaml.' && exit 0",
"test:codeblocks:telegraf": "docker compose run --rm --name telegraf-pytest telegraf-pytest",
"test:codeblocks:v1": "echo '⚠️ InfluxDB v1 pytest service not yet configured. Add v1-pytest to compose.yaml.' && exit 0",
"test:codeblocks:v2": "docker compose run --rm --name v2-pytest v2-pytest",
"test:codeblocks:stop-monitors": "./test/scripts/monitor-tests.sh stop cloud-dedicated-pytest && ./test/scripts/monitor-tests.sh stop clustered-pytest",
"test:codeblocks:python": "echo 'Testing Python code blocks...' && docker compose run --rm cloud-pytest bash -c './test/scripts/test-by-language.sh python content/influxdb/cloud/**/*.md'",
"test:codeblocks:bash": "echo 'Testing Bash/Shell code blocks...' && docker compose run --rm cloud-pytest bash -c './test/scripts/test-by-language.sh bash content/influxdb/cloud/**/*.md'",
"test:codeblocks:sql": "echo 'Testing SQL code blocks...' && docker compose run --rm cloud-pytest bash -c './test/scripts/test-by-language.sh sql content/influxdb/cloud/**/*.md'",
Comment on lines +102 to +104
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test:codeblocks:{python,bash,sql} commands use docker compose run ... cloud-pytest bash -c ..., but the cloud-pytest service has an entrypoint of /src/test/scripts/run-tests.sh pytest (see compose.yaml). As written, bash -c ... becomes arguments to run-tests.sh rather than executing your script, so these commands won’t work. Use --entrypoint bash (or add a dedicated service without the test runner entrypoint) when you need to run ad-hoc commands.

Suggested change
"test:codeblocks:python": "echo 'Testing Python code blocks...' && docker compose run --rm cloud-pytest bash -c './test/scripts/test-by-language.sh python content/influxdb/cloud/**/*.md'",
"test:codeblocks:bash": "echo 'Testing Bash/Shell code blocks...' && docker compose run --rm cloud-pytest bash -c './test/scripts/test-by-language.sh bash content/influxdb/cloud/**/*.md'",
"test:codeblocks:sql": "echo 'Testing SQL code blocks...' && docker compose run --rm cloud-pytest bash -c './test/scripts/test-by-language.sh sql content/influxdb/cloud/**/*.md'",
"test:codeblocks:python": "echo 'Testing Python code blocks...' && docker compose run --rm --entrypoint bash cloud-pytest -lc './test/scripts/test-by-language.sh python content/influxdb/cloud/**/*.md'",
"test:codeblocks:bash": "echo 'Testing Bash/Shell code blocks...' && docker compose run --rm --entrypoint bash cloud-pytest -lc './test/scripts/test-by-language.sh bash content/influxdb/cloud/**/*.md'",
"test:codeblocks:sql": "echo 'Testing SQL code blocks...' && docker compose run --rm --entrypoint bash cloud-pytest -lc './test/scripts/test-by-language.sh sql content/influxdb/cloud/**/*.md'",

Copilot uses AI. Check for mistakes.
"test:cache:stats": "./test/scripts/manage-test-cache.sh stats",
"test:cache:clean": "./test/scripts/manage-test-cache.sh clean",
"test:cache:clear": "./test/scripts/manage-test-cache.sh clear",
"test:cache:list": "./test/scripts/manage-test-cache.sh list",
"test:e2e": "node cypress/support/run-e2e-specs.js",
"test:shortcode-examples": "node cypress/support/run-e2e-specs.js --spec \"cypress/e2e/content/index.cy.js\" content/example.md",
"sync-plugins": "cd helper-scripts/influxdb3-plugins && node port_to_docs.js",
Expand Down
101 changes: 101 additions & 0 deletions scripts/ci/detect-test-products.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env node
/**
* Detect which products need testing based on changed content files.
*
* Usage:
* echo "content/influxdb3/core/page.md" | node scripts/ci/detect-test-products.js
* node scripts/ci/detect-test-products.js < changed-files.txt
*
* Output (JSON):
* {"products":["influxdb3_core","telegraf"],"files":["content/influxdb3/core/page.md",...]}
*
* This script:
* 1. Reads changed file paths from stdin (one per line)
* 2. Expands shared content changes to find all affected product pages
* 3. Extracts unique products from the affected file paths
* 4. Outputs JSON with products array and expanded files array
*/

import { expandSharedContentChanges } from '../lib/content-utils.js';

// Product path mappings
const PRODUCT_PATTERNS = [
{ pattern: /^content\/influxdb3\/core\//, product: 'influxdb3_core' },
{ pattern: /^content\/influxdb3\/enterprise\//, product: 'influxdb3_enterprise' },
{ pattern: /^content\/influxdb3\/cloud-dedicated\//, product: 'cloud-dedicated' },
{ pattern: /^content\/influxdb3\/cloud-serverless\//, product: 'cloud-serverless' },
{ pattern: /^content\/influxdb3\/clustered\//, product: 'clustered' },
{ pattern: /^content\/influxdb3\/explorer\//, product: 'explorer' },
{ pattern: /^content\/influxdb\/cloud\//, product: 'cloud' },
{ pattern: /^content\/influxdb\/v2\//, product: 'v2' },
{ pattern: /^content\/influxdb\/v1\//, product: 'v1' },
{ pattern: /^content\/telegraf\//, product: 'telegraf' },
];

/**
* Extract product identifier from a content file path
* @param {string} filePath - Content file path
* @returns {string|null} Product identifier or null
*/
function getProductFromPath(filePath) {
for (const { pattern, product } of PRODUCT_PATTERNS) {
if (pattern.test(filePath)) {
return product;
}
}
return null;
}

/**
* Main function
*/
async function main() {
// Read changed files from stdin
const input = await new Promise((resolve) => {
let data = '';
process.stdin.setEncoding('utf8');
process.stdin.on('data', (chunk) => (data += chunk));
process.stdin.on('end', () => resolve(data));

// Handle case where stdin is empty/closed immediately
if (process.stdin.isTTY) {
resolve('');
}
});

const changedFiles = input
.trim()
.split('\n')
.filter((f) => f && f.endsWith('.md'));

if (changedFiles.length === 0) {
console.log(JSON.stringify({ products: [], files: [] }));
process.exit(0);
}

// Expand shared content changes to find all affected pages
const verbose = process.env.VERBOSE === 'true';
const expandedFiles = expandSharedContentChanges(changedFiles, { verbose });

// Extract unique products from expanded file list
const products = new Set();
for (const file of expandedFiles) {
const product = getProductFromPath(file);
if (product) {
products.add(product);
}
}

// Output JSON result
const result = {
products: Array.from(products).sort(),
files: expandedFiles.sort(),
};

console.log(JSON.stringify(result));
}

main().catch((err) => {
console.error('Error:', err.message);
process.exit(1);
});
Loading