Skip to content

Commit

Permalink
integration-tests: Actor updates to run against nightly
Browse files Browse the repository at this point in the history
- Modifies the existing actor tests to use predeployed contract addresses
- Exposes metrics about the actor via Prometheus

To see how the actors are set up using Stackman, see https://github.com/ethereum-optimism/stacks/blob/master/nightly/actors.yml.

Fixes ENG-1667
  • Loading branch information
mslipper committed Jan 4, 2022
1 parent f4cf99e commit 5787a55
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 69 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-zoos-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@eth-optimism/integration-tests': patch
---

Updates to support nightly actor tests
17 changes: 17 additions & 0 deletions integration-tests/actor-tests/lib/metrics.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import fs from 'fs'
import client from 'prom-client'
import http from 'http'
import url from 'url'

export const metricsRegistry = new client.Registry()

Expand Down Expand Up @@ -53,3 +55,18 @@ export const dumpMetrics = async (filename: string) => {
flag: 'w+',
})
}

export const serveMetrics = (port: number) => {
const server = http.createServer(async (req, res) => {
const route = url.parse(req.url).pathname
if (route !== '/metrics') {
res.writeHead(404)
res.end()
return
}

res.setHeader('Content-Type', metricsRegistry.contentType)
res.end(await metricsRegistry.metrics())
})
server.listen(port)
}
23 changes: 17 additions & 6 deletions integration-tests/actor-tests/lib/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { defaultRuntime } from './convenience'
import { RunOpts } from './actor'
import { Command } from 'commander'
import pkg from '../../package.json'
import { metricsRegistry } from './metrics'
import { serveMetrics } from './metrics'

const program = new Command()
program.version(pkg.version)
Expand All @@ -18,6 +18,11 @@ program
)
.option('-c, --concurrency <n>', 'number of concurrent workers to spawn', '1')
.option('--think-time <n>', 'how long to wait between each run', '0')
.option(
'-s, --serve [port]',
'Serve metrics with optional port number',
'8545'
)

program.parse(process.argv)

Expand All @@ -27,6 +32,8 @@ const runsNum = Number(options.runs)
const timeNum = Number(options.time)
const concNum = Number(options.concurrency)
const thinkNum = Number(options.thinkTime)
const shouldServeMetrics = options.serve !== undefined
const metricsPort = options.serve || 8545

if (isNaN(runsNum) && isNaN(timeNum)) {
console.error('Must define either a number of runs or how long to run.')
Expand Down Expand Up @@ -58,15 +65,19 @@ const opts: Partial<RunOpts> = {
runs: runsNum,
}

if (shouldServeMetrics) {
process.stderr.write(`Serving metrics on http://0.0.0.0:${metricsPort}.\n`)
serveMetrics(metricsPort)
}

defaultRuntime
.run(opts)
.then(() => metricsRegistry.metrics())
.then((metrics) => {
process.stderr.write('Run complete. Metrics:\n')
console.log(metrics)
.then(() => {
process.stderr.write('Run complete.\n')
process.exit(0)
})
.catch((err) => {
console.error('Error running:')
console.error('Error:')
console.error(err)
process.exit(1)
})
11 changes: 2 additions & 9 deletions integration-tests/actor-tests/nft.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { utils, Wallet, Contract, ContractFactory } from 'ethers'
import { utils, Wallet, Contract } from 'ethers'
import { actor, run, setupActor, setupRun } from './lib/convenience'
import { OptimismEnv } from '../test/shared/env'
import ERC721 from '../artifacts/contracts/NFT.sol/NFT.json'
Expand All @@ -16,14 +16,7 @@ actor('NFT claimer', () => {

setupActor(async () => {
env = await OptimismEnv.new()

const factory = new ContractFactory(
ERC721.abi,
ERC721.bytecode,
env.l2Wallet
)
contract = await factory.deploy()
await contract.deployed()
contract = new Contract(process.env.ERC_721_ADDRESS, ERC721.abi)
})

setupRun(async () => {
Expand Down
79 changes: 25 additions & 54 deletions integration-tests/actor-tests/uniswap.test.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import { BigNumber, Contract, utils, Wallet, ContractFactory } from 'ethers'
import { Contract, utils, Wallet } from 'ethers'
import { actor, run, setupActor, setupRun } from './lib/convenience'
import { OptimismEnv } from '../test/shared/env'
import { UniswapV3Deployer } from 'uniswap-v3-deploy-plugin/dist/deployer/UniswapV3Deployer'
import { FeeAmount, TICK_SPACINGS } from '@uniswap/v3-sdk'
import { FeeAmount } from '@uniswap/v3-sdk'
import ERC20 from '../artifacts/contracts/ERC20.sol/ERC20.json'
import { abi as NFTABI } from '@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json'
import { abi as RouterABI } from '@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json'

interface Context {
contracts: { [name: string]: Contract }
wallet: Wallet
}

// Below methods taken from the Uniswap test suite, see
// https://github.com/Uniswap/v3-periphery/blob/main/test/shared/ticks.ts
export const getMinTick = (tickSpacing: number) =>
Math.ceil(-887272 / tickSpacing) * tickSpacing
export const getMaxTick = (tickSpacing: number) =>
Math.floor(887272 / tickSpacing) * tickSpacing

actor('Uniswap swapper', () => {
let env: OptimismEnv

Expand All @@ -27,52 +21,29 @@ actor('Uniswap swapper', () => {
setupActor(async () => {
env = await OptimismEnv.new()

const factory = new ContractFactory(ERC20.abi, ERC20.bytecode, env.l2Wallet)
const tokenA = await factory.deploy(1000000000, 'OVM1', 8, 'OVM1')
await tokenA.deployed()
const tokenB = await factory.deploy(1000000000, 'OVM2', 8, 'OVM2')
await tokenB.deployed()

tokens =
tokenA.address < tokenB.address ? [tokenA, tokenB] : [tokenB, tokenA]
contracts = await UniswapV3Deployer.deploy(env.l2Wallet)

let tx
for (const token of tokens) {
tx = await token.approve(contracts.positionManager.address, 1000000000)
await tx.wait()
tx = await token.approve(contracts.router.address, 1000000000)
await tx.wait()
contracts = {
positionManager: new Contract(
process.env.UNISWAP_POSITION_MANAGER_ADDRESS,
NFTABI
).connect(env.l2Wallet),
router: new Contract(
process.env.UNISWAP_ROUTER_ADDRESS,
RouterABI
).connect(env.l2Wallet),
}

tx = await contracts.positionManager.createAndInitializePoolIfNecessary(
tokens[0].address,
tokens[1].address,
FeeAmount.MEDIUM,
// initial ratio of 1/1
BigNumber.from('79228162514264337593543950336')
)
await tx.wait()

tx = await contracts.positionManager.mint(
{
token0: tokens[0].address,
token1: tokens[1].address,
tickLower: getMinTick(TICK_SPACINGS[FeeAmount.MEDIUM]),
tickUpper: getMaxTick(TICK_SPACINGS[FeeAmount.MEDIUM]),
fee: FeeAmount.MEDIUM,
recipient: env.l2Wallet.address,
amount0Desired: 100000000,
amount1Desired: 100000000,
amount0Min: 0,
amount1Min: 0,
deadline: Date.now() * 2,
},
{
gasLimit: 10000000,
}
)
await tx.wait()
tokens = [
new Contract(process.env.UNISWAP_TOKEN_0_ADDRESS, ERC20.abi).connect(
env.l2Wallet
),
new Contract(process.env.UNISWAP_TOKEN_1_ADDRESS, ERC20.abi).connect(
env.l2Wallet
),
]
tokens =
tokens[0].address.toLowerCase() < tokens[1].address.toLowerCase()
? [tokens[0], tokens[1]]
: [tokens[1], tokens[0]]
})

setupRun(async () => {
Expand Down
1 change: 1 addition & 0 deletions integration-tests/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"sync-tests/*.ts",
"./actor-tests/**/*.ts",
"./artifacts/**/*.json",
"./tasks/**/*.ts",
"./package.json"
],
"files": ["./hardhat.config.ts"]
Expand Down

0 comments on commit 5787a55

Please sign in to comment.