-
Notifications
You must be signed in to change notification settings - Fork 759
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
5 changed files
with
246 additions
and
100 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,231 @@ | ||
/* eslint-disable no-console */ | ||
/** | ||
* Asynchronous Global Test Setup | ||
* Run only once | ||
* ref: order of execution jestGlobalSetup.ts -> jest.setup.ts -> fixtures.ts | ||
*/ | ||
|
||
import { BaseUrl } from '../src/constants'; | ||
|
||
type DevnetStrategy = { | ||
isDevnet: boolean; | ||
isRS: boolean; | ||
}; | ||
type ProviderType = { | ||
sequencer: boolean; | ||
rpc: boolean; | ||
}; | ||
|
||
/** | ||
* Global Setup Fixtures | ||
*/ | ||
|
||
/* Default test config based on run `starknet-devnet --seed 0` */ | ||
const GS_DEFAULT_TEST_PROVIDER_URL = 'http://127.0.0.1:5050/'; | ||
|
||
/** | ||
* We need to detect intention of the test runner | ||
* Does test run on local devnet? | ||
* Does it run Sequencer or RPC tests ? | ||
*/ | ||
const localDevnetDetectionStrategy = async () => { | ||
const setup = (strategy: DevnetStrategy) => { | ||
// Setup ENV | ||
process.env.IS_LOCALHOST_DEVNET = 'false'; | ||
process.env.IS_RPC_DEVNET = 'false'; | ||
process.env.IS_SEQUENCER_DEVNET = 'false'; | ||
|
||
if (strategy.isDevnet) { | ||
process.env.IS_LOCALHOST_DEVNET = 'true'; | ||
if (strategy.isRS) { | ||
process.env.IS_RPC_DEVNET = 'true'; | ||
} else { | ||
process.env.IS_SEQUENCER_DEVNET = 'true'; | ||
} | ||
} | ||
return strategy; | ||
}; | ||
|
||
const strategy: DevnetStrategy = { | ||
isDevnet: false, | ||
isRS: false, | ||
}; | ||
// if is_alive work it is local devnet | ||
try { | ||
const response = await fetch(`${GS_DEFAULT_TEST_PROVIDER_URL}is_alive`); | ||
const body = await response.text(); | ||
if (body === 'Alive!!!') { | ||
strategy.isDevnet = true; | ||
} else { | ||
return setup(strategy); | ||
} | ||
} catch (error) { | ||
return setup(strategy); | ||
} | ||
// if on base url RPC endpoint work it is devnet-rs else it devnet-py | ||
try { | ||
const response = await fetch(`${GS_DEFAULT_TEST_PROVIDER_URL}`, { | ||
method: 'POST', | ||
headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, | ||
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'starknet_syncing' }), | ||
}); | ||
const json = await response.json(); | ||
strategy.isRS = json.jsonrpc === '2.0'; | ||
} catch (error) { | ||
return setup(strategy); | ||
} | ||
|
||
const sequencerOrRpc = () => { | ||
return setup(strategy); | ||
}; | ||
|
||
const sequencerOrRpc = async (devnetStrategy?: DevnetStrategy) => { | ||
const setup = (providerType: ProviderType) => { | ||
process.env.IS_SEQUENCER = providerType.sequencer ? 'true' : 'false'; | ||
process.env.IS_RPC = providerType.rpc ? 'true' : 'false'; | ||
process.env.IS_SEQUENCER_GOERLI = ( | ||
process.env.TEST_PROVIDER_BASE_URL || | ||
process.env.TEST_RPC_URL || | ||
'' | ||
).includes(BaseUrl.SN_GOERLI) | ||
? 'true' | ||
: 'false'; | ||
return providerType; | ||
}; | ||
let result: ProviderType = { sequencer: false, rpc: false }; | ||
if (process.env.TEST_PROVIDER_BASE_URL) { | ||
return { sequencer: true, rpc: false }; | ||
return setup({ ...result, sequencer: true }); | ||
} | ||
if (process.env.TEST_RPC_URL) { | ||
return { sequencer: false, rpc: true }; | ||
return setup({ ...result, rpc: true }); | ||
} | ||
// nor sequencer nor rpc provided, try with local devnet strategy | ||
if (devnetStrategy && devnetStrategy.isDevnet) { | ||
result = { sequencer: !devnetStrategy.isRS, rpc: devnetStrategy.isRS }; | ||
if (result.sequencer) { | ||
process.env.TEST_PROVIDER_BASE_URL = GS_DEFAULT_TEST_PROVIDER_URL; | ||
} else if (result.rpc) { | ||
process.env.TEST_RPC_URL = GS_DEFAULT_TEST_PROVIDER_URL; | ||
} | ||
} | ||
// nor sequencer nor rpc provided, try with local devnet detection | ||
return { sequencer: false, rpc: false }; | ||
return setup(result); | ||
}; | ||
|
||
const isAccountProvided = () => { | ||
const setAccount = async (devnetStrategy: DevnetStrategy) => { | ||
const fetchAccount = async (URL: string) => { | ||
const response = await fetch(`${URL}predeployed_accounts`); | ||
const accounts = await response.json(); | ||
process.env.TEST_ACCOUNT_ADDRESS = accounts[0].address; | ||
process.env.TEST_ACCOUNT_PRIVATE_KEY = accounts[0].private_key; | ||
process.env.INITIAL_BALANCE = accounts[0].initial_balance; | ||
}; | ||
|
||
if (process.env.TEST_ACCOUNT_ADDRESS && process.env.TEST_ACCOUNT_PRIVATE_KEY) { | ||
return true; | ||
} | ||
if (process.env.TEST_ACCOUNT_ADDRESS || process.env.TEST_ACCOUNT_PRIVATE_KEY) { | ||
throw new Error( | ||
'If you are providing test Account you need to provide both TEST_ACCOUNT_ADDRESS & TEST_ACCOUNT_PRIVATE_KEY' | ||
'If you are providing one of you need to provide both: TEST_ACCOUNT_ADDRESS & TEST_ACCOUNT_PRIVATE_KEY' | ||
); | ||
} | ||
return false; | ||
const providedURL = process.env.TEST_PROVIDER_BASE_URL || process.env.TEST_RPC_URL; | ||
if (devnetStrategy.isDevnet) { | ||
// get account from devnet | ||
try { | ||
await fetchAccount(GS_DEFAULT_TEST_PROVIDER_URL); | ||
return true; | ||
} catch (error) { | ||
console.error('Fetching account from devnet failed'); | ||
} | ||
} else if (providedURL) { | ||
// try to get it from remote devnet | ||
try { | ||
await fetchAccount(providedURL); | ||
return true; | ||
} catch (error) { | ||
console.error(`Fetching account from provided url ${providedURL} failed`); | ||
} | ||
} | ||
|
||
// if not provided try to get it from BASE_URL | ||
// if unsecesfull throw an account error | ||
throw new Error( | ||
'Setting Account using all known strategies failed, please provide TEST_ACCOUNT_ADDRESS & TEST_ACCOUNT_PRIVATE_KEY' | ||
); | ||
}; | ||
|
||
const defineStrategy = async () => { | ||
// TODO: implement strategy detection | ||
// did user provide TEST_PROVIDER_BASE_URL or TEST_RPC_URL if so we know it is RPC or Sequencer test | ||
// if not we need to aute detect it | ||
// did user provide TEST_ACCOUNT_ADDRESS and TEST_ACCOUNT_PRIVATE_KEY | ||
// - if yes, use provided account | ||
// - if only one throw error | ||
// - if no run local devnet strategy | ||
// did user provide TEST_PROVIDER_BASE_URL or TEST_RPC_URL | ||
// - is local devnet running? | ||
// - if yes, use local devnet | ||
// get local devnet version and accounts | ||
sequencerOrRpc(); | ||
isAccountProvided(); | ||
const verifySetup = (final?: boolean) => { | ||
if (!process.env.TEST_ACCOUNT_ADDRESS) { | ||
if (final) { | ||
throw new Error('TEST_ACCOUNT_ADDRESS env is not set'); | ||
} else return false; | ||
} | ||
if (!process.env.TEST_ACCOUNT_PRIVATE_KEY) { | ||
if (final) { | ||
throw new Error('TEST_ACCOUNT_PRIVATE_KEY env is not set'); | ||
} else return false; | ||
} | ||
if (!process.env.TEST_PROVIDER_BASE_URL && !process.env.TEST_RPC_URL) { | ||
if (final) { | ||
throw new Error('One of TEST_PROVIDER_BASE_URL or TEST_RPC_URL env is not set'); | ||
} else return false; | ||
} | ||
|
||
console.table({ | ||
TEST_ACCOUNT_ADDRESS: process.env.TEST_ACCOUNT_ADDRESS, | ||
TEST_ACCOUNT_PRIVATE_KEY: '****', | ||
INITIAL_BALANCE: process.env.INITIAL_BALANCE, | ||
TEST_PROVIDER_BASE_URL: process.env.TEST_PROVIDER_BASE_URL, | ||
TEST_RPC_URL: process.env.TEST_RPC_URL, | ||
}); | ||
|
||
console.table({ | ||
IS_LOCALHOST_DEVNET: process.env.IS_LOCALHOST_DEVNET, | ||
IS_RPC_DEVNET: process.env.IS_RPC_DEVNET, | ||
IS_SEQUENCER_DEVNET: process.env.IS_SEQUENCER_DEVNET, | ||
IS_RPC: process.env.IS_RPC, | ||
IS_SEQUENCER: process.env.IS_SEQUENCER, | ||
IS_SEQUENCER_GOERLI: process.env.IS_SEQUENCER_GOERLI, | ||
}); | ||
|
||
console.log('Global Test Environment is Ready'); | ||
return true; | ||
}; | ||
|
||
const executeStrategy = async () => { | ||
// 1. Assume setup is provided and ready; | ||
let ready = verifySetup(); | ||
if (ready) { | ||
console.log('Using Provided Test Setup'); | ||
return true; | ||
} | ||
|
||
// 2. Try to detect setup | ||
console.log('Global Test Environment Auto Setup Started'); | ||
const devnetStrategy = await localDevnetDetectionStrategy(); | ||
if (devnetStrategy.isDevnet) { | ||
if (devnetStrategy.isRS) { | ||
console.log('Detected Devnet-RS'); | ||
} else { | ||
console.log('Detected Devnet-PY'); | ||
} | ||
} | ||
|
||
const providerType = await sequencerOrRpc(devnetStrategy); | ||
if (providerType.sequencer) { | ||
console.log('Detected Sequencer'); | ||
} else if (providerType.rpc) { | ||
console.log('Detected RPC'); | ||
} | ||
|
||
const isAccountSet = await setAccount(devnetStrategy); | ||
if (isAccountSet) { | ||
console.log('Detected Account'); | ||
} | ||
|
||
ready = await verifySetup(true); | ||
if (ready) { | ||
return true; | ||
} | ||
|
||
return false; | ||
}; | ||
|
||
module.exports = async function (_globalConfig: any, _projectConfig: any) { | ||
const devnetAccs = await defineStrategy(); | ||
console.log(devnetAccs); | ||
export default async (_globalConfig: any, _projectConfig: any) => { | ||
const isSet = await executeStrategy(); | ||
if (!isSet) console.error('Test Setup Environment is NOT Ready'); | ||
// SET GLOBALS | ||
process.env.GS_DEFAULT_TEST_PROVIDER_URL = GS_DEFAULT_TEST_PROVIDER_URL; | ||
}; |
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
Oops, something went wrong.