Skip to content
Draft
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
107 changes: 107 additions & 0 deletions docs/sources/k6/next/javascript-api/k6-x-dns/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
aliases:
title: 'k6/x/dns'
description: 'k6 DNS extension API'
weight: 11
---

# k6/x/dns

The `k6/x/dns` module enables DNS resolution testing in k6, allowing you to resolve DNS names to IP addresses using custom DNS servers or the system's default DNS configuration. This module is particularly useful for testing DNS server performance, validating DNS configurations, and incorporating DNS resolution into your load testing scenarios.

The DNS module is implemented as an official extension and is available natively in k6, requiring no additional installation or build steps thanks to native extensions support.

## Key features

- The [`dns.resolve()`](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-x-dns/resolve) function resolves DNS names using a specified DNS server, allowing you to test custom DNS configurations and server performance.
- The [`dns.lookup()`](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-x-dns/lookup) function resolves DNS names using the system's default DNS servers, providing a way to test standard DNS resolution behavior.
- Support for A (IPv4) and AAAA (IPv6) record types.
- Automatic metrics collection for DNS resolution performance analysis.

### Use cases

- Load testing DNS servers to ensure they can handle high query volumes.
- Validating DNS configurations in staging and production environments.
- Testing DNS failover mechanisms and redundancy.
- Incorporating DNS resolution time into overall application performance testing.

## API

| Function/Object | Description |
| ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [resolve](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-x-dns/resolve) | Resolves a DNS name to IP addresses using a specified DNS server. |
| [lookup](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/k6-x-dns/lookup) | Resolves a DNS name to IP addresses using the system's default DNS servers. |

## Metrics

The extension automatically generates the following metrics:

- `dns_resolutions`: Counter tracking the number of DNS resolution attempts.
- `dns_resolution_duration`: Trend measuring DNS resolution response times.
- `dns_lookups`: Counter tracking the number of DNS lookup attempts.
- `dns_lookup_duration`: Trend measuring DNS lookup response times.

## Examples

### Basic DNS resolution with custom server

{{< code >}}

```javascript
import dns from 'k6/x/dns';

export default async function () {
// Resolve k6.io using Cloudflare's DNS server
const ips = await dns.resolve('k6.io', 'A', '1.1.1.1:53');
console.log('k6.io resolves to:', ips);
}
```

{{< /code >}}

### DNS lookup using system defaults

{{< code >}}

```javascript
import dns from 'k6/x/dns';

export default async function () {
// Resolve k6.io using system DNS servers
const ips = await dns.lookup('k6.io');
console.log('k6.io resolves to:', ips);
}
```

{{< /code >}}

### Comprehensive DNS testing

{{< code >}}

```javascript
import dns from 'k6/x/dns';
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';

export const options = {
vus: 10,
duration: '30s',
};

export default async function () {
// Test both IPv4 and IPv6 resolution
const ipv4Results = await dns.resolve('example.com', 'A', '8.8.8.8:53');
const ipv6Results = await dns.resolve('example.com', 'AAAA', '[2606:4700:4700::1111]:53');

// Test system DNS
const systemResults = await dns.lookup('example.com');

// Validate results
expect(ipv4Results.length).toBeGreaterThan(0);
expect(ipv6Results.length).toBeGreaterThan(0);
expect(systemResults.length).toBeGreaterThan(0);
}
```

{{< /code >}}

252 changes: 252 additions & 0 deletions docs/sources/k6/next/javascript-api/k6-x-dns/lookup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
---
title: 'lookup( hostname )'
description: 'resolve a DNS name to IP addresses using system DNS servers'
weight: 30
---

# lookup( hostname )

The `dns.lookup` function performs DNS resolution using the system's default DNS configuration and returns a promise that resolves to an array of IP addresses. This function is useful, for instance, for testing standard DNS resolution behavior and comparing it with custom DNS server results.

## Parameters

| Parameter | Type | Description |
| :-------- | :----- | :------------------------------------------------------------------------ |
| hostname | string | The domain name to resolve (e.g., "example.com", "k6.io") |

## Returns

A promise resolving to an array of strings, where each string is an IP address that the domain name resolves to. The function returns the same IP addresses that would be returned by the system's standard DNS resolution mechanism.

## Examples

### Basic lookup

{{< code >}}

```javascript
import dns from 'k6/x/dns';

export default async function () {
// Resolve using system DNS servers
const addresses = await dns.lookup('k6.io');
console.log('k6.io resolves to:', addresses);
// Output: k6.io resolves to: ["104.21.7.127", "172.67.154.74"]
}
```

{{< /code >}}

### Comparing system vs custom DNS

{{< code >}}

```javascript
import dns from 'k6/x/dns';
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';

export default async function () {
const domain = 'example.com';

// Get results from system DNS
const systemResults = await dns.lookup(domain);

// Get results from Google's DNS
const googleResults = await dns.resolve(domain, 'A', '8.8.8.8:53');

console.log('System DNS results:', systemResults);
console.log('Google DNS results:', googleResults);

// Check if both methods return results
expect(systemResults.length).toBeGreaterThan(0);
expect(googleResults.length).toBeGreaterThan(0);

// Compare results (they might differ due to different DNS configurations)
const hasCommonAddress = systemResults.some(ip => googleResults.includes(ip));
expect(hasCommonAddress).toBeTruthy();
}
```

{{< /code >}}

### Testing DNS consistency

{{< code >}}

```javascript
import dns from 'k6/x/dns';
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';

export const options = {
vus: 1,
iterations: 10,
};

export default async function () {
const domain = 'k6.io';

try {
const results = await dns.lookup(domain);

expect(results.length).toBeGreaterThan(0);
expect(results.every(ip =>
/^\d+\.\d+\.\d+\.\d+$/.test(ip) || /^[0-9a-fA-F:]+$/.test(ip)
)).toBeTruthy();

console.log(`Iteration ${__ITER}: ${domain} -> ${results.join(', ')}`);
} catch (error) {
console.error('DNS lookup failed:', error);
}
}
```

{{< /code >}}

### Load testing with system DNS

{{< code >}}

```javascript
import dns from 'k6/x/dns';
import { sleep } from 'k6';
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
import { Trend, Rate } from 'k6/metrics';

const lookupDuration = new Trend('dns_lookup_duration_custom');
const successRate = new Rate('dns_lookup_success_rate');

export const options = {
vus: 10,
duration: '60s',
};

const domains = [
'k6.io',
'example.com',
'google.com',
'github.com',
'stackoverflow.com',
];

export default async function () {
const domain = domains[Math.floor(Math.random() * domains.length)];
const startTime = Date.now();

try {
const results = await dns.lookup(domain);
const duration = Date.now() - startTime;

lookupDuration.add(duration);
successRate.add(true);

expect(results.length).toBeGreaterThan(0);

console.log(`${domain} resolved in ${duration}ms to ${results.length} addresses`);
} catch (error) {
const duration = Date.now() - startTime;
lookupDuration.add(duration);
successRate.add(false);

console.error(`Failed to resolve ${domain}: ${error.message}`);
}

sleep(1);
}
```

{{< /code >}}

### Validating DNS configuration

{{< code >}}

```javascript
import dns from 'k6/x/dns';
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';

export default async function () {
const testDomains = [
'k6.io',
'grafana.com',
'example.com',
];

for (const domain of testDomains) {
try {
const results = await dns.lookup(domain);

expect(results.length).toBeGreaterThan(0);
expect(results.every(ip => {
// Basic IPv4/IPv6 validation
return /^\d+\.\d+\.\d+\.\d+$/.test(ip) || /^[0-9a-fA-F:]+$/.test(ip);
})).toBeTruthy();

console.log(`✓ ${domain}: ${results.join(', ')}`);
} catch (error) {
console.error(`✗ ${domain}: ${error.message}`);
}
}
}
```

{{< /code >}}

## Error handling

The `lookup` function may throw errors in the following cases:

- Invalid hostname format
- DNS resolution timeout
- No DNS servers configured on the system
- Network connectivity issues

{{< code >}}

```javascript
import dns from 'k6/x/dns';

export default async function () {
try {
const results = await dns.lookup('nonexistent.invalid.domain.test');
console.log('Unexpected success:', results);
} catch (error) {
console.log('Expected DNS lookup error:', error.message);
}

// Test with invalid hostname format
try {
const results = await dns.lookup('');
console.log('Unexpected success with empty hostname:', results);
} catch (error) {
console.log('Expected error for empty hostname:', error.message);
}
}
```

{{< /code >}}

## Metrics

When using `dns.lookup`, the following metrics are automatically generated:

- `dns_lookups`: Counter incremented for each lookup attempt
- `dns_lookup_duration`: Trend measuring the time taken for DNS lookup

These metrics help you monitor DNS performance using your system's DNS configuration.

## Notes on Usage

- **System dependency**: Results depend on your system's DNS configuration (resolv.conf on Unix systems, network settings on Windows)
- **Caching**: System DNS resolution may be cached, which can affect performance measurements
- **Comparison baseline**: Use `lookup` as a baseline when comparing performance against custom DNS servers
- **Network environment**: Results may vary between different network environments and configurations
- **IPv4/IPv6**: The function returns both IPv4 and IPv6 addresses if available, depending on your system's configuration

## Comparison with resolve()

| Feature | `dns.lookup()` | `dns.resolve()` |
|---------|----------------|-----------------|
| DNS server | System default | Custom specified |
| Configuration | Uses system settings | Full control |
| Caching | May use system cache | Direct server query |
| Use case | Standard resolution testing | Custom DNS server testing |
Loading
Loading