Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

convertConfig Tests #703

Merged
merged 6 commits into from
Feb 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ test-all: test-go test-wasm-node test-wasm-browser


.PHONY: test-go
test-go: test-go-parallel test-go-serial
test-go: test-go-parallel test-go-serial test-browser-conversion

.PHONY: test-go-parallel
test-go-parallel:
Expand All @@ -52,6 +52,9 @@ test-go-serial:
test-browser-integration:
go test ./integration-tests -timeout 185s --enable-browser-integration-tests -run BrowserIntegration

.PHONY: test-browser-conversion
test-browser-conversion:
go test ./browser/go/conversion-test -timeout 120s --enable-browser-conversion-tests -run BrowserConversions

.PHONY: test-wasm-node
test-wasm-node:
Expand Down
57 changes: 54 additions & 3 deletions browser/conversion-tests/conversion_test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { RPCSubprovider, Web3ProviderEngine } from '@0x/subproviders';
import { BigNumber, hexUtils, logUtils } from '@0x/utils';

import {
Expand All @@ -13,8 +14,10 @@ import {
ExchangeCancelEvent,
ExchangeCancelUpToEvent,
ExchangeFillEvent,
JsonSchema,
WethDepositEvent,
WethWithdrawalEvent,
WrapperConfig,
WrapperContractEvent,
WrapperERC1155TransferBatchEvent,
WrapperERC1155TransferSingleEvent,
Expand Down Expand Up @@ -51,6 +54,7 @@ interface ConversionTestCase {
orderEvents: () => WrapperOrderEvent[];
signedOrders: () => WrapperSignedOrder[];
stats: () => WrapperStats[];
testConvertConfig: (...configs: WrapperConfig[]) => void;
validationResults: () => WrapperValidationResults[];
}

Expand Down Expand Up @@ -117,15 +121,18 @@ WebAssembly.instantiateStreaming(fetch('conversion_test.wasm'), go.importObject)
//
// Verification has been very simple in practice as it has only entailed equality
// comparisons so far. These findings must be reported so that the conversion test
// entry-point knows whether or not individual tests succeed of fail. The current
// methodology for reporting findings is to print a string of the from: "$description: true."
// entry-point knows whether or not individual tests succeed or fail. The current
// methodology for reporting findings is to print a string of the from: "$description: true".
// These printed strings are received by the test's entry-point, which can then verify
// that the print statement corresponds to a registered "test case" in the entry-point.
// The entry-point verifies that all registered tests have passed, and it also has
// features that will cause the test to fail if (1) unexpected logs are received or (2)
// if some test cases were not tested.
(async () => {
// Wait for the Wasm module to finish initializing.
await waitForLoadAsync();

// Execute the Go --> Typescript tests
const contractEvents = conversionTestCases.contractEvents();
testContractEvents(contractEvents);
const getOrdersResponse = conversionTestCases.getOrdersResponse();
Expand All @@ -139,6 +146,50 @@ WebAssembly.instantiateStreaming(fetch('conversion_test.wasm'), go.importObject)
const validationResults = conversionTestCases.validationResults();
testValidationResults(validationResults);

// Execute the Typescript --> Go tests
const ethereumRPCURL = 'http://localhost:8545';

// Set up a Web3 Provider that uses the RPC endpoint
// tslint:disable:no-object-literal-type-assertion
const provider = new Web3ProviderEngine();
provider.addProvider(new RPCSubprovider(ethereumRPCURL));
conversionTestCases.testConvertConfig(
...[
(null as unknown) as WrapperConfig,
(undefined as unknown) as WrapperConfig,
{} as WrapperConfig,
{ ethereumChainID: 1337 },
configToWrapperConfig({
ethereumChainID: 1337,
verbosity: 5,
useBootstrapList: false,
bootstrapList: [
'/ip4/3.214.190.67/tcp/60558/ipfs/16Uiu2HAmGx8Z6gdq5T5AQE54GMtqDhDFhizywTy1o28NJbAMMumF',
'/ip4/3.214.190.67/tcp/60557/ipfs/16Uiu2HAmGx8Z6gdq5T5AQE54GMtqDhDFhizywTy1o28NJbAMMumG',
],
blockPollingIntervalSeconds: 2,
ethereumRPCMaxContentLength: 524100,
ethereumRPCMaxRequestsPer24HrUTC: 500000,
ethereumRPCMaxRequestsPerSecond: 12,
enableEthereumRPCRateLimiting: false,
customContractAddresses: {
exchange: '0x48bacb9266a570d521063ef5dd96e61686dbe788',
devUtils: '0x38ef19fdf8e8415f18c307ed71967e19aac28ba1',
erc20Proxy: '0x1dc4c1cefef38a777b15aa20260a54e584b16c48',
erc721Proxy: '0x1d7022f5b17d2f8b695918fb48fa1089c9f85401',
erc1155Proxy: '0x64517fa2b480ba3678a2a3c0cf08ef7fd4fad36f',
},
maxOrdersInStorage: 500000,
customOrderFilter: {
id: '/foobarbaz',
},
ethereumRPCURL: 'http://localhost:8545',
web3Provider: provider,
}),
],
);
// tslint:enable:no-object-literal-type-assertion

// This special #jsFinished div is used to signal the headless Chrome driver
// that the JavaScript code is done running. This is not a native Javascript
// concept. Rather, it is our way of letting the Go program that serves this
Expand All @@ -147,7 +198,7 @@ WebAssembly.instantiateStreaming(fetch('conversion_test.wasm'), go.importObject)
finishedDiv.setAttribute('id', 'jsFinished');
document.body.appendChild(finishedDiv);
})().catch(err => {
throw err;
console.log(err);
});

function prettyPrintTestCase(name: string, description: string): (section: string, value: boolean) => void {
Expand Down
91 changes: 91 additions & 0 deletions browser/go/browserutil/browserutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// +build js, wasm

// NOTE(jalextowle): This file contains utilities used by browser based mesh nodes
// that need to be tested and would cause cyclic dependencies if they were moved
// to jsutil.
package browserutil

import (
"errors"
"syscall/js"
"time"

"github.com/0xProject/0x-mesh/browser/go/jsutil"
"github.com/0xProject/0x-mesh/browser/go/providerwrapper"
"github.com/0xProject/0x-mesh/core"
"github.com/0xProject/0x-mesh/orderfilter"
)

// ConvertConfig converts a JavaScript config object into a core.Config. It also
// adds default values for any that are missing in the JavaScript object.
func ConvertConfig(jsConfig js.Value) (core.Config, error) {
if jsutil.IsNullOrUndefined(jsConfig) {
return core.Config{}, errors.New("config is required")
}

// Default config options. Some might be overridden.
config := core.Config{
Verbosity: 2,
DataDir: "0x-mesh",
P2PTCPPort: 0,
P2PWebSocketsPort: 0,
UseBootstrapList: true,
BlockPollingInterval: 5 * time.Second,
EthereumRPCMaxContentLength: 524288,
EthereumRPCMaxRequestsPer24HrUTC: 100000,
EthereumRPCMaxRequestsPerSecond: 30,
EnableEthereumRPCRateLimiting: true,
MaxOrdersInStorage: 100000,
CustomOrderFilter: orderfilter.DefaultCustomOrderSchema,
}

// Required config options
if ethereumChainID := jsConfig.Get("ethereumChainID"); jsutil.IsNullOrUndefined(ethereumChainID) {
return core.Config{}, errors.New("ethereumChainID is required")
} else {
config.EthereumChainID = ethereumChainID.Int()
}

// Optional config options
if verbosity := jsConfig.Get("verbosity"); !jsutil.IsNullOrUndefined(verbosity) {
config.Verbosity = verbosity.Int()
}
if useBootstrapList := jsConfig.Get("useBootstrapList"); !jsutil.IsNullOrUndefined(useBootstrapList) {
config.UseBootstrapList = useBootstrapList.Bool()
}
if bootstrapList := jsConfig.Get("bootstrapList"); !jsutil.IsNullOrUndefined(bootstrapList) {
config.BootstrapList = bootstrapList.String()
}
if blockPollingIntervalSeconds := jsConfig.Get("blockPollingIntervalSeconds"); !jsutil.IsNullOrUndefined(blockPollingIntervalSeconds) {
config.BlockPollingInterval = time.Duration(blockPollingIntervalSeconds.Int()) * time.Second
}
if ethereumRPCMaxContentLength := jsConfig.Get("ethereumRPCMaxContentLength"); !jsutil.IsNullOrUndefined(ethereumRPCMaxContentLength) {
config.EthereumRPCMaxContentLength = ethereumRPCMaxContentLength.Int()
}
if ethereumRPCMaxRequestsPer24HrUTC := jsConfig.Get("ethereumRPCMaxRequestsPer24HrUTC"); !jsutil.IsNullOrUndefined(ethereumRPCMaxRequestsPer24HrUTC) {
config.EthereumRPCMaxRequestsPer24HrUTC = ethereumRPCMaxRequestsPer24HrUTC.Int()
}
if ethereumRPCMaxRequestsPerSecond := jsConfig.Get("ethereumRPCMaxRequestsPerSecond"); !jsutil.IsNullOrUndefined(ethereumRPCMaxRequestsPerSecond) {
config.EthereumRPCMaxRequestsPerSecond = ethereumRPCMaxRequestsPerSecond.Float()
}
if enableEthereumRPCRateLimiting := jsConfig.Get("enableEthereumRPCRateLimiting"); !jsutil.IsNullOrUndefined(enableEthereumRPCRateLimiting) {
config.EnableEthereumRPCRateLimiting = enableEthereumRPCRateLimiting.Bool()
}
if customContractAddresses := jsConfig.Get("customContractAddresses"); !jsutil.IsNullOrUndefined(customContractAddresses) {
config.CustomContractAddresses = customContractAddresses.String()
}
if maxOrdersInStorage := jsConfig.Get("maxOrdersInStorage"); !jsutil.IsNullOrUndefined(maxOrdersInStorage) {
config.MaxOrdersInStorage = maxOrdersInStorage.Int()
}
if customOrderFilter := jsConfig.Get("customOrderFilter"); !jsutil.IsNullOrUndefined(customOrderFilter) {
config.CustomOrderFilter = customOrderFilter.String()
}
if ethereumRPCURL := jsConfig.Get("ethereumRPCURL"); !jsutil.IsNullOrUndefined(ethereumRPCURL) && ethereumRPCURL.String() != "" {
config.EthereumRPCURL = ethereumRPCURL.String()
}
if web3Provider := jsConfig.Get("web3Provider"); !jsutil.IsNullOrUndefined(web3Provider) {
config.EthereumRPCClient = providerwrapper.NewRPCClient(web3Provider)
}

return config, nil
}
40 changes: 36 additions & 4 deletions browser/go/conversion-test/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package main

import (
"context"
"flag"
"fmt"
"net/http"
"net/http/httptest"
Expand All @@ -19,6 +20,16 @@ import (

var testCases []string

var browserConversionTestsEnabled bool

// The test `TestBrowserConversions` has a non-standard timeout, so it needs to be
// run seperately from other go tests.
func init() {
flag.BoolVar(&browserConversionTestsEnabled, "enable-browser-conversion-tests", false, "enable browser conversion tests")
testing.Init()
flag.Parse()
}

// This test is the entry-point to the Browser Conversion Tests. The other relevant
// files are "../../conversion-test/conversion_test.ts" and "./main.go."
//
Expand All @@ -33,15 +44,19 @@ var testCases []string
// failures, unexpected tests, and missing tests are all failure conditions for this
// test.
func TestBrowserConversions(t *testing.T) {
if !browserConversionTestsEnabled {
t.Skip("Browser conversion tests are disabled. You can enable them with the --enable-browser-conversion-tests flag")
}

// Declare a context that will be used for all child processes, servers, and
// other goroutines.
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
ctx, _ = chromedp.NewContext(ctx, chromedp.WithErrorf(t.Errorf))
defer cancel()

jalextowle marked this conversation as resolved.
Show resolved Hide resolved
buildForTests(t, ctx)

// Register the test cases that should be logged.
// Register the Go --> Typescript test cases that should be logged.
registerContractEventTest()
registerGetOrdersResponseTest("EmptyOrderInfo", 0)
registerGetOrdersResponseTest("OneOrderInfo", 1)
Expand All @@ -56,6 +71,13 @@ func TestBrowserConversions(t *testing.T) {
registerValidationResultsTest("OneRejectedResult", 0, 1)
registerValidationResultsTest("RealisticValidationResults", 2, 1)

// Register the Typescript --> Go test cases that should be logged.
registerConvertConfigTest("NullConfig")
registerConvertConfigTest("UndefinedConfig")
registerConvertConfigTest("EmptyConfig")
registerConvertConfigTest("MinimalConfig")
registerConvertConfigTest("FullConfig")

// Start a simple HTTP server to serve the web page for the browser node.
ts := httptest.NewServer(http.FileServer(http.Dir("../../dist")))
defer ts.Close()
Expand Down Expand Up @@ -208,6 +230,16 @@ func registerContractEventField(description string, field string) {
registerTest(fmt.Sprintf("(contractEvent | %s | %s)", description, field))
}

func registerConvertConfigTest(description string) {
registerConvertConfigField(description, "config")
registerConvertConfigField(description, "web3Provider")
registerConvertConfigField(description, "err")
}

func registerConvertConfigField(description string, field string) {
registerTest(fmt.Sprintf("(convertConfig | %s | %s)", description, field))
}

func registerGetOrdersResponseTest(description string, orderInfoLength int) {
registerGetOrdersResponseField(description, "snapshotID")
registerGetOrdersResponseField(description, "snapshotTimestamp")
Expand Down Expand Up @@ -411,8 +443,8 @@ func startBrowserInstance(t *testing.T, ctx context.Context, url string, done ch
if count == testLength {
done <- struct{}{}
}
} else {
t.Errorf("Unexpected test results: %s", arg.Value)
} else if len(string(arg.Value)) > 1 {
t.Errorf("Unexpected test results: %s\n", string(arg.Value))
}
}
case runtime.APITypeError:
Expand Down
Loading