-
Notifications
You must be signed in to change notification settings - Fork 8
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
17 changed files
with
384 additions
and
6 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
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
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
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,3 +1,26 @@ | ||
# e2e | ||
|
||
TODO: docs | ||
> End to end test utilizing Mock API, pusher and signed API. | ||
## Getting started | ||
|
||
1. If you are using Docker Desktop, you need to change the URL in `pusher/secrets.env` from `localhost` to | ||
`host.docker.internal`, because pusher is running inside a Docker container. | ||
2. Build the latest Docker images. Run `pnpm run docker:build` from the monorepo root. The e2e flow uses the docker | ||
images. | ||
3. This module contains services (or configurations) that are integrated together. Specifically: | ||
|
||
- `pusher` - Contains the configuration for the pusher service. | ||
- `signed-api` - Contains the configuration for the signed API service. | ||
- `data-provider-api.ts` - Contains the configuration for the data provider API service (mocked express server). | ||
- `user.ts` - Contains the configuration for the user service (infinite fetch from signed API). | ||
|
||
You are free to modify the configurations to test different scenarios. | ||
|
||
4. There are `start:<some-service>` scripts to start the services. It is recommended to start each service in a separate | ||
terminal and in this order: | ||
|
||
1. `pnpm run start:data-provider-api` | ||
2. `pnpm run start:signed-api` | ||
3. `pnpm run start:pusher` | ||
4. `pnpm run start:user` |
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
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,52 @@ | ||
import express from 'express'; | ||
import { logger } from './logger'; | ||
|
||
const app = express(); | ||
const PORT = 9876 || process.env.PORT; | ||
|
||
interface Asset { | ||
value: number; | ||
// Everytime the API is queried, the value will be updated by a random percentage. | ||
deltaPercent: number; | ||
name: string; | ||
} | ||
|
||
const assets: Asset[] = [ | ||
{ | ||
value: 1000, | ||
deltaPercent: 10, | ||
name: 'MOCK-ETH/USD', | ||
}, | ||
{ | ||
value: 5000, | ||
deltaPercent: 2, | ||
name: 'MOCK-BTC/USD', | ||
}, | ||
{ | ||
value: 750, | ||
deltaPercent: 80, | ||
name: 'MOCK-ABC/DEF', | ||
}, | ||
{ | ||
value: 50000, | ||
deltaPercent: 20, | ||
name: 'MOCK-HJK/KOP', | ||
}, | ||
]; | ||
|
||
app.get('/', (_req, res) => { | ||
logger.debug('Request GET /'); | ||
|
||
for (const asset of assets) { | ||
asset.value = parseFloat((asset.value * (1 + ((Math.random() - 0.5) * asset.deltaPercent) / 100)).toFixed(5)); | ||
} | ||
|
||
const response = Object.fromEntries(assets.map((asset) => [asset.name, asset.value])); | ||
logger.debug('Response GET /', response); | ||
|
||
res.json(response); | ||
}); | ||
|
||
app.listen(PORT, () => { | ||
logger.info(`Server is running on http://localhost:${PORT}`); | ||
}); |
This file was deleted.
Oops, something went wrong.
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,8 @@ | ||
import { createLogger } from 'signed-api/common'; | ||
|
||
export const logger = createLogger({ | ||
colorize: true, | ||
enabled: true, | ||
minLevel: 'debug', | ||
format: 'pretty', | ||
}); |
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,4 @@ | ||
LOGGER_ENABLED=true | ||
LOG_COLORIZE=true | ||
LOG_FORMAT=pretty | ||
LOG_LEVEL=debug |
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,111 @@ | ||
{ | ||
"airnodeWalletMnemonic": "diamond result history offer forest diagram crop armed stumble orchard stage glance", | ||
"rateLimiting": { "Mock API": { "maxConcurrency": 25, "minTime": 0 } }, | ||
"templates": { | ||
"0xd1c9c79ccb6e24f77c14456b9b037ded9bfd0709468297e4e1e1bedbfe1bbf1a": { | ||
"endpointId": "0xa02c7e24d1d73f429927eedb78185a7d7d7c82d410acc3914cf6213aa29fea3f", | ||
"parameters": [{ "type": "string32", "name": "name", "value": "MOCK-ETH/USD" }] | ||
}, | ||
"0x4edc7440a34c8420ff592e4b2455785a9218c388a3112a2a92beedcb3e8feeba": { | ||
"endpointId": "0xa02c7e24d1d73f429927eedb78185a7d7d7c82d410acc3914cf6213aa29fea3f", | ||
"parameters": [{ "type": "string32", "name": "name", "value": "MOCK-BTC/USD" }] | ||
}, | ||
"0xcc72aa1d058c5db90c4595a6fcfb320dce997b978dcb6d1f176a121c05d47eeb": { | ||
"endpointId": "0xa02c7e24d1d73f429927eedb78185a7d7d7c82d410acc3914cf6213aa29fea3f", | ||
"parameters": [{ "type": "string32", "name": "name", "value": "MOCK-ABC/DEF" }] | ||
}, | ||
"0xcd2516b29a7634861a010155a3666b1be9af9cdb2d442e8f1ac1607c42862f9e": { | ||
"endpointId": "0xa02c7e24d1d73f429927eedb78185a7d7d7c82d410acc3914cf6213aa29fea3f", | ||
"parameters": [{ "type": "string32", "name": "name", "value": "MOCK-HJK/KOP" }] | ||
} | ||
}, | ||
"endpoints": { | ||
"0xa02c7e24d1d73f429927eedb78185a7d7d7c82d410acc3914cf6213aa29fea3f": { | ||
"endpointName": "mock-feed", | ||
"oisTitle": "Mock API" | ||
} | ||
}, | ||
"triggers": { | ||
"signedApiUpdates": [ | ||
{ | ||
"signedApiName": "localhost", | ||
"templateIds": [ | ||
"0xd1c9c79ccb6e24f77c14456b9b037ded9bfd0709468297e4e1e1bedbfe1bbf1a", | ||
"0x4edc7440a34c8420ff592e4b2455785a9218c388a3112a2a92beedcb3e8feeba" | ||
], | ||
"fetchInterval": 5, | ||
"updateDelay": 0 | ||
}, | ||
{ | ||
"signedApiName": "localhost", | ||
"templateIds": [ | ||
"0x4edc7440a34c8420ff592e4b2455785a9218c388a3112a2a92beedcb3e8feeba", | ||
"0xcc72aa1d058c5db90c4595a6fcfb320dce997b978dcb6d1f176a121c05d47eeb", | ||
"0xcd2516b29a7634861a010155a3666b1be9af9cdb2d442e8f1ac1607c42862f9e" | ||
], | ||
"fetchInterval": 3, | ||
"updateDelay": 5 | ||
}, | ||
{ | ||
"signedApiName": "localhost", | ||
"templateIds": [ | ||
"0xd1c9c79ccb6e24f77c14456b9b037ded9bfd0709468297e4e1e1bedbfe1bbf1a", | ||
"0xcc72aa1d058c5db90c4595a6fcfb320dce997b978dcb6d1f176a121c05d47eeb", | ||
"0xcd2516b29a7634861a010155a3666b1be9af9cdb2d442e8f1ac1607c42862f9e" | ||
], | ||
"fetchInterval": 1, | ||
"updateDelay": 0 | ||
} | ||
] | ||
}, | ||
"signedApis": [ | ||
{ | ||
"name": "localhost", | ||
"url": "http://${HOST_IP}:8090" | ||
} | ||
], | ||
"ois": [ | ||
{ | ||
"oisFormat": "2.2.0", | ||
"title": "Mock API", | ||
"version": "0.2.0", | ||
"apiSpecifications": { | ||
"components": { | ||
"securitySchemes": {} | ||
}, | ||
"paths": { | ||
"/": { "get": { "parameters": [] } } | ||
}, | ||
"servers": [{ "url": "http://${HOST_IP}:9876" }], | ||
"security": {} | ||
}, | ||
"endpoints": [ | ||
{ | ||
"fixedOperationParameters": [], | ||
"name": "mock-feed", | ||
"operation": { "method": "get", "path": "/" }, | ||
"parameters": [{ "name": "name" }], | ||
"reservedParameters": [ | ||
{ "name": "_type", "fixed": "int256" }, | ||
{ "name": "_times", "fixed": "1000000000000000000" } | ||
], | ||
"preProcessingSpecifications": [ | ||
{ | ||
"environment": "Node", | ||
"value": "const output = {};", | ||
"timeoutMs": 5000 | ||
} | ||
], | ||
"postProcessingSpecifications": [ | ||
{ | ||
"environment": "Node", | ||
"value": "const output = input[endpointParameters.name];", | ||
"timeoutMs": 5000 | ||
} | ||
] | ||
} | ||
] | ||
} | ||
], | ||
"apiCredentials": [] | ||
} |
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,4 @@ | ||
# Secrets must NOT be quoted. | ||
# | ||
# Use "host.docker.internal" if using Docker for Desktop. | ||
HOST_IP=localhost |
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,16 @@ | ||
LOGGER_ENABLED=true | ||
LOG_COLORIZE=true | ||
LOG_FORMAT=pretty | ||
LOG_LEVEL=debug | ||
|
||
# Available options | ||
# local (default) - loads config/signed-api.json from the filesystem | ||
# aws-s3 - loads the config file from AWS S3 | ||
CONFIG_SOURCE=local | ||
|
||
# Set these variables if you would like to source your config from AWS S3 | ||
AWS_ACCESS_KEY_ID= | ||
AWS_SECRET_ACCESS_KEY= | ||
AWS_REGION= | ||
AWS_S3_BUCKET_NAME= | ||
AWS_S3_BUCKET_PATH= |
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,17 @@ | ||
{ | ||
"endpoints": [ | ||
{ | ||
"urlPath": "/real-time", | ||
"delaySeconds": 0 | ||
}, | ||
{ | ||
"urlPath": "/delayed", | ||
"delaySeconds": 10 | ||
} | ||
], | ||
"maxBatchSize": 10, | ||
"port": 8090, | ||
"cache": { | ||
"maxAgeSeconds": 0 | ||
} | ||
} |
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,28 @@ | ||
import axios from 'axios'; | ||
import { airnode, formatData } from './utils'; | ||
|
||
it('respects the delay', async () => { | ||
const start = Date.now(); | ||
let [realCount, delayedCount] = [0, 0]; | ||
|
||
while (Date.now() - start < 15_000) { | ||
const realTimeResponse = await axios.get(`http://localhost:8090/real-time/${airnode}`); | ||
const realTimeData = formatData(realTimeResponse.data); | ||
const delayedResponse = await axios.get(`http://localhost:8090/delayed/${airnode}`); | ||
const delayedData = formatData(delayedResponse.data); | ||
|
||
for (const data of realTimeData) { | ||
expect(data.delay).toBeGreaterThan(0); | ||
realCount++; | ||
} | ||
for (const data of delayedData) { | ||
expect(data.delay).toBeGreaterThan(10_000); | ||
delayedCount++; | ||
} | ||
|
||
await new Promise((resolve) => setTimeout(resolve, 300)); | ||
} | ||
|
||
expect(realCount).toBeGreaterThan(0); | ||
expect(delayedCount).toBeGreaterThan(0); | ||
}, 20_000); |
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,20 @@ | ||
import axios from 'axios'; | ||
import { logger } from './logger'; | ||
import { airnode, formatData } from './utils'; | ||
|
||
async function main() { | ||
// eslint-disable-next-line no-constant-condition | ||
while (true) { | ||
logger.debug('Making requests'); | ||
|
||
const realTimeResponse = await axios.get(`http://localhost:8090/real-time/${airnode}`); | ||
logger.debug('Response GET /real-time', formatData(realTimeResponse.data)); | ||
|
||
const delayedResponse = await axios.get(`http://localhost:8090/delayed/${airnode}`); | ||
logger.debug('Response GET /delayed', formatData(delayedResponse.data)); | ||
|
||
await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
} | ||
} | ||
|
||
main(); |
Oops, something went wrong.