add multiple tabs in browser test

call tests in ci yml
This commit is contained in:
shamb0t 2019-07-18 09:28:17 +01:00
parent b9a941e1fd
commit e636629cf9
8 changed files with 1238 additions and 769 deletions

View File

@ -76,7 +76,7 @@ jobs:
# Test
# This would typically be a build job when using workflows, possibly combined with build
# The following line was run implicitly in your 1.0 builds based on what CircleCI inferred about the structure of your project. In 2.0 you need to be explicit about which commands should be run. In some cases you can discard inferred commands if they are not relevant to your project.
- run: npm test
- run: npm run test:all
# Teardown
# If you break your build into multiple jobs with workflows, you will probably want to do the parts of this that are relevant in each
# Save test results

9
.gitignore vendored
View File

@ -4,6 +4,15 @@ orbitdb/
# Don't distribute the dependencies
node_modules/
#Don't track ipfs files
test/ipfs/
test/browser/ipfs/
test/browser/orbitdb/
test/browser/orbitdb.js
test/browser/ipfs.js
test/browser/ipfslog.min.js
test/browser/identities.js
# Don't track examples' dependencies (libs) in git
examples/browser/browser-webpack-example/bundle.js
examples/browser/browser-webpack-example/*.map

View File

@ -4,7 +4,7 @@ deps:
npm install
test: deps
npm run test
npm run test:all
build: test
mkdir -p examples/browser/lib/

1804
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -22,14 +22,14 @@
"orbit-db-cache": "~0.2.4",
"orbit-db-counterstore": "~1.5.0",
"orbit-db-docstore": "~1.5.0",
"orbit-db-eventstore": "~1.5.0",
"orbit-db-eventstore": "github:orbitdb/orbit-db-eventstore#fix/load",
"orbit-db-feedstore": "~1.5.0",
"orbit-db-identity-provider": "~0.1.0",
"orbit-db-io": "~0.1.0",
"orbit-db-keystore": "^0.2.1",
"orbit-db-kvstore": "~1.5.0",
"orbit-db-pubsub": "~0.5.5",
"orbit-db-store": "~2.6.0"
"orbit-db-store": "github:orbitdb/orbit-db-store#fix/load"
},
"devDependencies": {
"babel-core": "^6.26.0",
@ -39,7 +39,7 @@
"babel-preset-env": "^1.7.0",
"datastore-level": "0.10.0",
"fs-extra": "^7.0.1",
"go-ipfs-dep": "0.4.19",
"go-ipfs-dep": "~0.4.20",
"ipfs": "~0.36.4",
"ipfs-repo": "~0.26.6",
"ipfsd-ctl": "~0.42.3",
@ -51,6 +51,7 @@
"p-map-series": "^1.0.0",
"p-whilst": "^1.0.0",
"pify": "^4.0.1",
"puppeteer": "^1.18.1",
"remark-cli": "^5.0.0",
"remark-validate-links": "^7.0.0",
"rimraf": "^2.6.2",
@ -63,7 +64,9 @@
"examples:browser-macos": "open examples/browser/browser.html",
"examples:browser-linux": "xdg-open examples/browser/browser.html",
"lint:docs": "remark -qf -u validate-links .",
"test:all": "npm run test:browser-multiple-tabs && npm run test",
"test": "TEST=all mocha",
"test:browser-multiple-tabs": "npm run build:dist && cp dist/orbitdb.min.js ./test/browser/orbitdb.js && cp node_modules/ipfs/dist/index.js ./test/browser/ipfs.js && cp node_modules/orbit-db-identity-provider/dist/index-browser.min.js ./test/browser/identities.js && cp node_modules/ipfs-log/dist/ipfslog.min.js ./test/browser/ipfslog.min.js && mocha ./test/browser/concurrent.spec.js",
"build": "npm run build:es5 && npm run build:debug && npm run build:dist && npm run build:examples && npm run build:docs/toc",
"build:examples": "webpack --config conf/webpack.example.config.js --sort-modules-by size && mkdir -p examples/browser/lib && cp node_modules/ipfs/dist/index.js examples/browser/lib/ipfs.js",
"build:dist": "webpack --config conf/webpack.config.js --sort-modules-by size && mkdir -p examples/browser/lib && cp dist/orbitdb.min.js examples/browser/lib/orbitdb.min.js",

View File

@ -0,0 +1,97 @@
'use strict'
const assert = require('assert')
const puppeteer = require('puppeteer')
const path = require('path')
const mapSeries = require('p-map-series')
const pMap = require('p-map')
const {
config,
} = require('../utils')
const clicksPerTab = 30
const numTabs = 2
describe(`orbit-db - browser concurrent writes`, function() {
this.timeout(config.timeout)
let browser
const options = {
ignoreHTTPSErrors: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
}
before(async () => {
browser = await puppeteer.launch(options)
})
after(async () => {
await browser.close()
})
describe('Write concurrently', function() {
it('Multiple tabs converge to same log', async () => {
const createTab = async () => {
const page = await browser.newPage()
await page.goto(`file://${path.resolve(__dirname, 'index.html')}`)
page.on('dialog', dialog => dialog.dismiss())
page.on('pageerror', err => console.error(err))
return page
}
// open several tabs
const tabs = []
for (let i = 0; i < numTabs; i++) {
const tab = await createTab()
tabs.push(tab)
}
const addDataButton = 'button#addData'
await pMap(tabs, async (page) => {
await page.waitForFunction(
'document.querySelector("#waitForOpenDB").innerText.includes("orbitdb")'
)
const addDataToLog = (maxClicks, maxWaitTime) => {
let count = 0
const repeat = () => new Promise((resolve, reject) => {
setTimeout(async () => {
await page.click(addDataButton)
if (++count < maxClicks) {
await repeat()
}
resolve()
}, Math.random() * maxWaitTime + 250) // ensure waiting at least ~250ms
})
return repeat()
}
return addDataToLog(clicksPerTab, 1000)
})
return new Promise((resolve, reject) => {
let polls = 0
const interval = setInterval(async () => {
let logHashes = []
await mapSeries(tabs, async (page) => {
await page.evaluate(() => loadLog())
const hash = await page.evaluate(async () => await getLogHash())
logHashes.push(hash)
})
try {
const hashes = Array.from(new Set(logHashes))
// ensure log hashes are equal
assert.strictEqual(hashes.length, 1)
clearInterval(interval)
resolve()
} catch (e) {
console.log("Repolling...")
if (++polls > 5) {
reject(e)
}
}
}, 3000)
})
})
})
})

81
test/browser/index.html Normal file
View File

@ -0,0 +1,81 @@
<html>
<head>
<title>Break OrbitDB</title>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<script type="text/javascript" src="orbitdb.js" charset="utf-8"></script>
<script type="text/javascript" src="ipfs.js" charset="utf-8"></script>
<script type="text/javascript" src="identities.js" charset="utf-8"></script>
<script type="text/javascript" src="ipfslog.min.js" charset="utf-8"></script>
</head>
<body>
<div style="padding: 0px 0px 25px 0px;">
<p>
<span id="waitForOpenDB"></span>
</p>
<button id="addData" type="button">Add random data</button>
<hr />
<h3> Log Data </h3>
<p>
<span id="logData"></span>
</p>
</div>
<!-- </div> -->
<script type="text/javascript">
const randStr = () => Math.random().toString(36).substring(6)
const ipfs = new Ipfs({
repo: './odb/',
EXPERIMENTAL: {
pubsub: true
},
preload: { enabled: false },
config: {
Bootstrap: [ ]
}
})
async function getLogLength () {
return window.log._oplog.length
}
async function getLogHash () {
return await window.log._oplog.toMultihash()
}
async function loadLog () {
await window.log.load()
}
async function getEntries () {
return window.log.iterator({ limit: -1 }).collect()
}
async function getSortFn () {
return [{hash: 'b', clock: {id: 'A', time: 1}}, {hash: 'a', clock: {id: 'A', time: 1}}].sort(window.log._oplog._sortFn)
}
ipfs.on('ready', async () => {
const identity = await Identities.createIdentity({ id: 'A'})
const orbitdb = await OrbitDB.createInstance(ipfs, { identity })
console.log(Log.Sorting.SortByEntryHash.toString())
let log = await orbitdb.log('concurrent', { syncLocal: true })
window.log = log
waitForOpenDB.innerHTML = log.address.toString()
await log.load()
const updateData = () => {
logData.innerHTML = ''
const count = log.iterator({ limit: -1 }).collect().map(e => {
logData.innerHTML += e.clock.time + ': ' + e.hash + '<br />'
})
}
addData.addEventListener('click', async event => {
const data = randStr()
await log.add(data)
updateData()
})
})
</script>
</body>
</html>

View File

@ -2,4 +2,5 @@
--colors
--recursive
--exit
--slow 1000
--slow 1000
--exclude test/browser/**/*.js