Skip to content

Commit 0ef876e

Browse files
authored
Merge pull request #2073 from grafana/document-k6-x-dns
docs: add comprehensive k6/x/dns extension documentation
2 parents e540866 + 6b7e5fc commit 0ef876e

File tree

5 files changed

+471
-44
lines changed

5 files changed

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

0 commit comments

Comments
 (0)