Skip to content

Commit 81b9c46

Browse files
committed
docs: add comprehensive k6/x/dns extension documentation
- Add complete documentation for k6/x/dns module with _index.md overview - Create resolve.md documenting dns.resolve() function with parameters, examples, and error handling - Create lookup.md documenting dns.lookup() function for system DNS resolution - Include installation instructions, API reference, and metrics documentation - Add comprehensive examples for IPv4/IPv6 resolution, performance testing, and validation - Use IPv6 DNS server (2606:4700:4700::1111) in IPv6 examples for consistency - Replace check() usage with k6-jslib-testing expect() assertions throughout examples - Follow k6 documentation conventions matching existing API documentation structure
1 parent 34f5bd4 commit 81b9c46

File tree

4 files changed

+530
-44
lines changed

4 files changed

+530
-44
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
---
2+
aliases:
3+
title: 'k6/x/dns'
4+
description: 'k6 DNS extension API'
5+
weight: 11
6+
---
7+
8+
# k6/x/dns
9+
10+
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.
11+
12+
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.
13+
14+
## Key features
15+
16+
- 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.
17+
- 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.
18+
- Support for A (IPv4) and AAAA (IPv6) record types.
19+
- Automatic metrics collection for DNS resolution performance analysis.
20+
21+
### Use cases
22+
23+
- Load testing DNS servers to ensure they can handle high query volumes.
24+
- Validating DNS configurations in staging and production environments.
25+
- Testing DNS failover mechanisms and redundancy.
26+
- Incorporating DNS resolution time into overall application performance testing.
27+
28+
## API
29+
30+
| Function/Object | Description |
31+
| ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
32+
| [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. |
33+
| [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. |
34+
35+
## Metrics
36+
37+
The extension automatically generates the following metrics:
38+
39+
- `dns_resolutions`: Counter tracking the number of DNS resolution attempts.
40+
- `dns_resolution_duration`: Trend measuring DNS resolution response times.
41+
- `dns_lookups`: Counter tracking the number of DNS lookup attempts.
42+
- `dns_lookup_duration`: Trend measuring DNS lookup response times.
43+
44+
## Examples
45+
46+
### Basic DNS resolution with custom server
47+
48+
{{< code >}}
49+
50+
```javascript
51+
import dns from 'k6/x/dns';
52+
53+
export default async function () {
54+
// Resolve k6.io using Cloudflare's DNS server
55+
const ips = await dns.resolve('k6.io', 'A', '1.1.1.1:53');
56+
console.log('k6.io resolves to:', ips);
57+
}
58+
```
59+
60+
{{< /code >}}
61+
62+
### DNS lookup using system defaults
63+
64+
{{< code >}}
65+
66+
```javascript
67+
import dns from 'k6/x/dns';
68+
69+
export default async function () {
70+
// Resolve k6.io using system DNS servers
71+
const ips = await dns.lookup('k6.io');
72+
console.log('k6.io resolves to:', ips);
73+
}
74+
```
75+
76+
{{< /code >}}
77+
78+
### Comprehensive DNS testing
79+
80+
{{< code >}}
81+
82+
```javascript
83+
import dns from 'k6/x/dns';
84+
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
85+
86+
export const options = {
87+
vus: 10,
88+
duration: '30s',
89+
};
90+
91+
export default async function () {
92+
// Test both IPv4 and IPv6 resolution
93+
const ipv4Results = await dns.resolve('example.com', 'A', '8.8.8.8:53');
94+
const ipv6Results = await dns.resolve('example.com', 'AAAA', '[2606:4700:4700::1111]:53');
95+
96+
// Test system DNS
97+
const systemResults = await dns.lookup('example.com');
98+
99+
// Validate results
100+
expect(ipv4Results.length).toBeGreaterThan(0);
101+
expect(ipv6Results.length).toBeGreaterThan(0);
102+
expect(systemResults.length).toBeGreaterThan(0);
103+
}
104+
```
105+
106+
{{< /code >}}
107+
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
---
2+
title: 'lookup( hostname )'
3+
description: 'resolve a DNS name to IP addresses using system DNS servers'
4+
weight: 30
5+
---
6+
7+
# lookup( hostname )
8+
9+
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.
10+
11+
## Parameters
12+
13+
| Parameter | Type | Description |
14+
| :-------- | :----- | :------------------------------------------------------------------------ |
15+
| hostname | string | The domain name to resolve (e.g., "example.com", "k6.io") |
16+
17+
## Returns
18+
19+
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.
20+
21+
## Examples
22+
23+
### Basic lookup
24+
25+
{{< code >}}
26+
27+
```javascript
28+
import dns from 'k6/x/dns';
29+
30+
export default async function () {
31+
// Resolve using system DNS servers
32+
const addresses = await dns.lookup('k6.io');
33+
console.log('k6.io resolves to:', addresses);
34+
// Output: k6.io resolves to: ["104.21.7.127", "172.67.154.74"]
35+
}
36+
```
37+
38+
{{< /code >}}
39+
40+
### Comparing system vs custom DNS
41+
42+
{{< code >}}
43+
44+
```javascript
45+
import dns from 'k6/x/dns';
46+
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
47+
48+
export default async function () {
49+
const domain = 'example.com';
50+
51+
// Get results from system DNS
52+
const systemResults = await dns.lookup(domain);
53+
54+
// Get results from Google's DNS
55+
const googleResults = await dns.resolve(domain, 'A', '8.8.8.8:53');
56+
57+
console.log('System DNS results:', systemResults);
58+
console.log('Google DNS results:', googleResults);
59+
60+
// Check if both methods return results
61+
expect(systemResults.length).toBeGreaterThan(0);
62+
expect(googleResults.length).toBeGreaterThan(0);
63+
64+
// Compare results (they might differ due to different DNS configurations)
65+
const hasCommonAddress = systemResults.some(ip => googleResults.includes(ip));
66+
expect(hasCommonAddress).toBeTruthy();
67+
}
68+
```
69+
70+
{{< /code >}}
71+
72+
### Testing DNS consistency
73+
74+
{{< code >}}
75+
76+
```javascript
77+
import dns from 'k6/x/dns';
78+
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
79+
80+
export const options = {
81+
vus: 1,
82+
iterations: 10,
83+
};
84+
85+
export default async function () {
86+
const domain = 'k6.io';
87+
88+
try {
89+
const results = await dns.lookup(domain);
90+
91+
expect(results.length).toBeGreaterThan(0);
92+
expect(results.every(ip =>
93+
/^\d+\.\d+\.\d+\.\d+$/.test(ip) || /^[0-9a-fA-F:]+$/.test(ip)
94+
)).toBeTruthy();
95+
96+
console.log(`Iteration ${__ITER}: ${domain} -> ${results.join(', ')}`);
97+
} catch (error) {
98+
console.error('DNS lookup failed:', error);
99+
}
100+
}
101+
```
102+
103+
{{< /code >}}
104+
105+
### Load testing with system DNS
106+
107+
{{< code >}}
108+
109+
```javascript
110+
import dns from 'k6/x/dns';
111+
import { sleep } from 'k6';
112+
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
113+
import { Trend, Rate } from 'k6/metrics';
114+
115+
const lookupDuration = new Trend('dns_lookup_duration_custom');
116+
const successRate = new Rate('dns_lookup_success_rate');
117+
118+
export const options = {
119+
vus: 10,
120+
duration: '60s',
121+
};
122+
123+
const domains = [
124+
'k6.io',
125+
'example.com',
126+
'google.com',
127+
'github.com',
128+
'stackoverflow.com',
129+
];
130+
131+
export default async function () {
132+
const domain = domains[Math.floor(Math.random() * domains.length)];
133+
const startTime = Date.now();
134+
135+
try {
136+
const results = await dns.lookup(domain);
137+
const duration = Date.now() - startTime;
138+
139+
lookupDuration.add(duration);
140+
successRate.add(true);
141+
142+
expect(results.length).toBeGreaterThan(0);
143+
144+
console.log(`${domain} resolved in ${duration}ms to ${results.length} addresses`);
145+
} catch (error) {
146+
const duration = Date.now() - startTime;
147+
lookupDuration.add(duration);
148+
successRate.add(false);
149+
150+
console.error(`Failed to resolve ${domain}: ${error.message}`);
151+
}
152+
153+
sleep(1);
154+
}
155+
```
156+
157+
{{< /code >}}
158+
159+
### Validating DNS configuration
160+
161+
{{< code >}}
162+
163+
```javascript
164+
import dns from 'k6/x/dns';
165+
import { expect } from 'https://jslib.k6.io/k6-testing/{{< param "JSLIB_TESTING_VERSION" >}}/index.js';
166+
167+
export default async function () {
168+
const testDomains = [
169+
'k6.io',
170+
'grafana.com',
171+
'example.com',
172+
];
173+
174+
for (const domain of testDomains) {
175+
try {
176+
const results = await dns.lookup(domain);
177+
178+
expect(results.length).toBeGreaterThan(0);
179+
expect(results.every(ip => {
180+
// Basic IPv4/IPv6 validation
181+
return /^\d+\.\d+\.\d+\.\d+$/.test(ip) || /^[0-9a-fA-F:]+$/.test(ip);
182+
})).toBeTruthy();
183+
184+
console.log(`${domain}: ${results.join(', ')}`);
185+
} catch (error) {
186+
console.error(`${domain}: ${error.message}`);
187+
}
188+
}
189+
}
190+
```
191+
192+
{{< /code >}}
193+
194+
## Error handling
195+
196+
The `lookup` function may throw errors in the following cases:
197+
198+
- Invalid hostname format
199+
- DNS resolution timeout
200+
- No DNS servers configured on the system
201+
- Network connectivity issues
202+
203+
{{< code >}}
204+
205+
```javascript
206+
import dns from 'k6/x/dns';
207+
208+
export default async function () {
209+
try {
210+
const results = await dns.lookup('nonexistent.invalid.domain.test');
211+
console.log('Unexpected success:', results);
212+
} catch (error) {
213+
console.log('Expected DNS lookup error:', error.message);
214+
}
215+
216+
// Test with invalid hostname format
217+
try {
218+
const results = await dns.lookup('');
219+
console.log('Unexpected success with empty hostname:', results);
220+
} catch (error) {
221+
console.log('Expected error for empty hostname:', error.message);
222+
}
223+
}
224+
```
225+
226+
{{< /code >}}
227+
228+
## Metrics
229+
230+
When using `dns.lookup`, the following metrics are automatically generated:
231+
232+
- `dns_lookups`: Counter incremented for each lookup attempt
233+
- `dns_lookup_duration`: Trend measuring the time taken for DNS lookup
234+
235+
These metrics help you monitor DNS performance using your system's DNS configuration.
236+
237+
## Notes on Usage
238+
239+
- **System dependency**: Results depend on your system's DNS configuration (resolv.conf on Unix systems, network settings on Windows)
240+
- **Caching**: System DNS resolution may be cached, which can affect performance measurements
241+
- **Comparison baseline**: Use `lookup` as a baseline when comparing performance against custom DNS servers
242+
- **Network environment**: Results may vary between different network environments and configurations
243+
- **IPv4/IPv6**: The function returns both IPv4 and IPv6 addresses if available, depending on your system's configuration
244+
245+
## Comparison with resolve()
246+
247+
| Feature | `dns.lookup()` | `dns.resolve()` |
248+
|---------|----------------|-----------------|
249+
| DNS server | System default | Custom specified |
250+
| Configuration | Uses system settings | Full control |
251+
| Caching | May use system cache | Direct server query |
252+
| Use case | Standard resolution testing | Custom DNS server testing |

0 commit comments

Comments
 (0)