-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
361 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import http from "http"; | ||
import {AddressInfo} from "net"; | ||
|
||
export class CloudflareMockServer { | ||
server: http.Server | undefined; | ||
|
||
start() { | ||
let self = this; | ||
this.server = http.createServer((req, res) => { | ||
var body = ""; | ||
req.on('readable', function() { | ||
let part = req.read(); | ||
if (part !== undefined && part !== null) { | ||
body += part; | ||
} | ||
}); | ||
req.on('end', function() { | ||
res.statusCode = 200; | ||
res.setHeader('Content-Type', 'text/plain'); | ||
res.end('OK'); | ||
}); | ||
}); | ||
this.server.listen(() => { | ||
console.log('opened server on', self.server?.address()); | ||
}); | ||
} | ||
|
||
url() { | ||
const { port } = this.server?.address() as AddressInfo; | ||
return `http://localhost:${port}/`; | ||
} | ||
|
||
async dispose() { | ||
if (this.server != undefined) { | ||
this.server.close(); | ||
this.server = undefined; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import {Log, LogLevel, Miniflare} from "miniflare"; | ||
import { MockAgent } from "undici"; | ||
|
||
export class MiniflareDriver { | ||
mockAgent = new MockAgent(); | ||
mf: Miniflare | undefined; | ||
|
||
start(options?: {metricsUrl?: string, cloudflareApiUrl?: string}): Miniflare { | ||
this.mockAgent | ||
.get("https://cloudflare.com") | ||
.intercept({ path: "/" }) | ||
.reply(200, "cloudflare!"); | ||
|
||
this.mockAgent | ||
.get("https://jsonplaceholder.typicode.com") | ||
.intercept({ path: "/todos/1" }) | ||
.reply( | ||
200, | ||
{ | ||
userId: 1, | ||
id: 1, | ||
title: "delectus aut autem", | ||
completed: false, | ||
}, | ||
{ | ||
headers: { | ||
"content-type": "application/json", | ||
}, | ||
} | ||
); | ||
|
||
let metricsUrl = ""; | ||
let cloudflareApiUrl = ""; | ||
if (options !== undefined) { | ||
if (options.metricsUrl !== undefined) { | ||
metricsUrl = options.metricsUrl; | ||
} | ||
if (options.cloudflareApiUrl !== undefined) { | ||
cloudflareApiUrl = options.cloudflareApiUrl; | ||
} | ||
} | ||
|
||
this.mf = new Miniflare({ | ||
log: new Log(LogLevel.DEBUG), // Enable debug messages | ||
cachePersist: false, | ||
d1Persist: false, | ||
kvPersist: false, | ||
r2Persist: false, | ||
workers: [{ | ||
scriptPath: "./build/worker/shim.mjs", | ||
compatibilityDate: "2022-04-05", | ||
cache: true, | ||
modules: true, | ||
modulesRules: [ | ||
{ type: "CompiledWasm", include: ["**/*.wasm"], fallthrough: true }, | ||
], | ||
fetchMock: this.mockAgent, | ||
}]}); | ||
return this.mf; | ||
} | ||
|
||
dispose() { | ||
if (this.mf === undefined) { | ||
return; | ||
} | ||
let promise = this.mf.dispose(); | ||
this.mf = undefined; | ||
return promise; | ||
} | ||
|
||
async trigger() { | ||
this.start({}); | ||
await this.mf?.dispatchFetch("http://localhost:8787/cdn-cgi/mf/scheduled"); | ||
this.dispose(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,33 @@ | ||
import {Given, When, Then} from '@cucumber/cucumber'; | ||
import {After, Given, When, Then} from '@cucumber/cucumber'; | ||
import {cloudflareMockServer, mf, mfConfig, otelServer} from "./state"; | ||
import {expect} from "chai"; | ||
|
||
Given('Worker is configured to point to mock Cloudflare API', function () { | ||
// Write code here that turns the phrase above into concrete actions | ||
return 'pending'; | ||
cloudflareMockServer.start(); | ||
mfConfig.cloudflareApiUrl = cloudflareMockServer.url(); | ||
}); | ||
|
||
Given('Worker is configured to send metrics to a mock OpenTelemetry collector', function () { | ||
// Write code here that turns the phrase above into concrete actions | ||
return 'pending'; | ||
otelServer.start(); | ||
mfConfig.metricsUrl = otelServer.metricsUrl(); | ||
}); | ||
|
||
When('Worker is triggered', function () { | ||
// Write code here that turns the phrase above into concrete actions | ||
return 'pending'; | ||
When('Worker is triggered', async function () { | ||
await mf.trigger(); | ||
}); | ||
|
||
Then('Worker metrics are published', function () { | ||
// Write code here that turns the phrase above into concrete actions | ||
return 'pending'; | ||
let metrics = otelServer.getMetrics(); | ||
expect(metrics).to.have.length.gte(1); | ||
}); | ||
|
||
|
||
Then('Meter name should include {string}', function (string) { | ||
// Write code here that turns the phrase above into concrete actions | ||
return 'pending'; | ||
Then('Meter name should include {string}', function (metricName: string) { | ||
let metricNames = otelServer.getMetricNames(); | ||
expect(metricNames).to.contain(metricName); | ||
}); | ||
|
||
After(async function () { | ||
await mf.dispose(); | ||
await cloudflareMockServer.dispose(); | ||
await otelServer.dispose(); | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import http from 'http'; | ||
import {IExportMetricsServiceRequest} from "@opentelemetry/otlp-transformer"; | ||
import {AddressInfo} from "net"; | ||
|
||
export class OpenTelemetryServer { | ||
server: http.Server | undefined; | ||
metrics: IExportMetricsServiceRequest[] = []; | ||
metricNames: Map<string, number> = new Map<string, number>(); | ||
|
||
private reset() { | ||
this.metrics = []; | ||
this.indexMetrics(); | ||
} | ||
|
||
start() { | ||
let self = this; | ||
self.reset(); | ||
this.server = http.createServer((req, res) => { | ||
var body = ""; | ||
req.on('readable', function() { | ||
let part = req.read(); | ||
if (part !== undefined && part !== null) { | ||
body += part; | ||
} | ||
}); | ||
req.on('end', function() { | ||
const metrics = JSON.parse(body) as IExportMetricsServiceRequest; | ||
self.metrics.push(metrics); | ||
self.indexMetrics(); | ||
res.statusCode = 200; | ||
res.setHeader('Content-Type', 'text/plain'); | ||
res.end('OK'); | ||
}); | ||
}); | ||
this.server.listen(() => { | ||
console.log('opened server on', self.server?.address()); | ||
}); | ||
} | ||
|
||
indexMetrics() { | ||
let self = this; | ||
this.metricNames.clear(); | ||
for (let metrics of this.metrics) { | ||
for (let resourceMetrics of metrics.resourceMetrics) { | ||
for (let scopeMetrics of resourceMetrics.scopeMetrics) { | ||
for (let metric of scopeMetrics.metrics) { | ||
self.metricNames.set(metric.name, 1); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
metricsUrl() { | ||
const { port } = this.server?.address() as AddressInfo; | ||
return `http://localhost:${port}/v1/metrics`; | ||
} | ||
|
||
async dispose() { | ||
if (this.server != undefined) { | ||
this.server.close(); | ||
this.server = undefined; | ||
} | ||
} | ||
|
||
getMetrics() { | ||
return this.metrics; | ||
} | ||
|
||
getMetricNames() { | ||
return this.metricNames.keys(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import {MiniflareDriver} from "./mf"; | ||
import {OpenTelemetryServer} from "./otel_server"; | ||
import {CloudflareMockServer} from "./cf_mock_server"; | ||
|
||
const mf = new MiniflareDriver(); | ||
const otelServer = new OpenTelemetryServer(); | ||
const cloudflareMockServer = new CloudflareMockServer(); | ||
|
||
type MfConfig = { | ||
metricsUrl: string|undefined; | ||
cloudflareApiUrl: string|undefined | ||
}; | ||
|
||
const mfConfig: MfConfig = { | ||
metricsUrl: undefined, | ||
cloudflareApiUrl: undefined, | ||
} | ||
|
||
export { mf, mfConfig, otelServer, cloudflareMockServer }; |
Oops, something went wrong.