From 2effb008466838500aca82c4b927ab2f9f3626a9 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 19 Apr 2018 23:58:26 +0900 Subject: [PATCH] add basic interop test --- interop/README.md | 4 + interop/go/main.go | 87 ++++++++++++ interop/js/.gitignore | 1 + interop/js/package-lock.json | 250 +++++++++++++++++++++++++++++++++++ interop/js/package.json | 14 ++ interop/js/server.js | 51 +++++++ interop/test.sh | 18 +++ 7 files changed, 425 insertions(+) create mode 100644 interop/README.md create mode 100644 interop/go/main.go create mode 100644 interop/js/.gitignore create mode 100644 interop/js/package-lock.json create mode 100644 interop/js/package.json create mode 100644 interop/js/server.js create mode 100755 interop/test.sh diff --git a/interop/README.md b/interop/README.md new file mode 100644 index 0000000..590f250 --- /dev/null +++ b/interop/README.md @@ -0,0 +1,4 @@ +# Js/Go interop test + +This directory contains a basic js/go interop test. To run it, just run +`./test.sh` in this directory. It depends on `npm` and `go`. diff --git a/interop/go/main.go b/interop/go/main.go new file mode 100644 index 0000000..e791f2b --- /dev/null +++ b/interop/go/main.go @@ -0,0 +1,87 @@ +package main + +import ( + "fmt" + "io" + "io/ioutil" + "net" + "sync" + + mplex "github.com/libp2p/go-mplex" +) + +var jsTestData = "test data from js %d" +var goTestData = "test data from go %d" + +func main() { + conn, err := net.Dial("tcp4", "127.0.0.1:9991") + if err != nil { + panic(err) + } + sess := mplex.NewMultiplex(conn, true) + defer sess.Close() + + var wg sync.WaitGroup + + for i := 0; i < 100; i++ { + wg.Add(1) + + go func() { + defer wg.Done() + s, err := sess.NewStream() + if err != nil { + panic(err) + } + readWrite(s) + }() + } + for i := 0; i < 100; i++ { + s, err := sess.Accept() + if err != nil { + panic(err) + } + wg.Add(1) + go func() { + defer wg.Done() + readWrite(s) + }() + } + wg.Wait() +} + +func readWrite(s *mplex.Stream) { + var wg sync.WaitGroup + wg.Add(2) + go func() { + defer wg.Done() + for i := 0; i < 100; i++ { + _, err := fmt.Fprintf(s, goTestData, i) + if err != nil { + panic(err) + } + } + s.Close() + }() + go func() { + defer wg.Done() + for i := 0; i < 100; i++ { + expected := fmt.Sprintf(jsTestData, i) + actual := make([]byte, len(expected)) + _, err := io.ReadFull(s, actual) + if err != nil { + panic(err) + } + if expected != string(actual) { + panic("bad bytes") + } + } + buf, err := ioutil.ReadAll(s) + if err != nil { + panic(err) + } + if len(buf) > 0 { + panic("expected EOF") + } + }() + wg.Wait() +} diff --git a/interop/js/.gitignore b/interop/js/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/interop/js/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/interop/js/package-lock.json b/interop/js/package-lock.json new file mode 100644 index 0000000..7b6ece6 --- /dev/null +++ b/interop/js/package-lock.json @@ -0,0 +1,250 @@ +{ + "name": "mplex-test", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "requires": { + "lodash": "4.17.5" + } + }, + "buffer-from": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", + "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==" + }, + "chunky": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/chunky/-/chunky-0.0.0.tgz", + "integrity": "sha1-HnWAojwIOJfSrWYkWefv2EZfYIo=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "1.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "typedarray": "0.0.6" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "duplexify": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz", + "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==", + "requires": { + "end-of-stream": "1.4.1", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "stream-shift": "1.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "1.4.0" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "interface-connection": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/interface-connection/-/interface-connection-0.3.2.tgz", + "integrity": "sha1-5JSYg/bqeft+3QHuP0/KR6Kf0sQ=", + "requires": { + "pull-defer": "0.2.2", + "timed-tape": "0.1.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "libp2p-mplex": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/libp2p-mplex/-/libp2p-mplex-0.7.0.tgz", + "integrity": "sha512-Vvk6ShXrNQBM/fkbrnEMtWuWiKEBXmSMFONtmfu33BKgi6dDzOWOR33LuIv1xEPkLWagRAeckVTg0kTta7J3ZA==", + "requires": { + "async": "2.6.0", + "chunky": "0.0.0", + "concat-stream": "1.6.2", + "debug": "3.1.0", + "duplexify": "3.5.4", + "pull-catch": "1.0.0", + "pull-stream": "3.6.7", + "pull-stream-to-stream": "1.3.4", + "pump": "3.0.0", + "readable-stream": "2.3.6", + "stream-to-pull-stream": "1.7.2", + "through2": "2.0.3", + "varint": "5.0.0" + } + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" + }, + "looper": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz", + "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "pull-catch": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pull-catch/-/pull-catch-1.0.0.tgz", + "integrity": "sha1-9YA361woLMtQavn3awAn0zkx5Is=" + }, + "pull-defer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.2.tgz", + "integrity": "sha1-CIew/7MK8ypW2+z6csFnInHwexM=" + }, + "pull-stream": { + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.7.tgz", + "integrity": "sha512-XdE2/o1I2lK7A+sbbA/HjYnd5Xk7wL5CwAKzqHIgcBsluDb0LiKHNTl1K0it3/RKPshQljLf4kl1aJ12YsCCGQ==" + }, + "pull-stream-to-stream": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/pull-stream-to-stream/-/pull-stream-to-stream-1.3.4.tgz", + "integrity": "sha1-P4HYIWvRjSv9GhmBkEcRgOJzg5k=" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + }, + "stream-to-pull-stream": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.2.tgz", + "integrity": "sha1-dXYJrhzr0zx0MtSvvjH/eGULnd4=", + "requires": { + "looper": "3.0.0", + "pull-stream": "3.6.7" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tcp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tcp/-/tcp-1.0.0.tgz", + "integrity": "sha1-/HZmWltMFMo5EyVwQ8BwdvqGqn4=" + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "2.3.6", + "xtend": "4.0.1" + } + }, + "timed-tape": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/timed-tape/-/timed-tape-0.1.1.tgz", + "integrity": "sha1-m25WnxfmbHnx7tLSX/eWL8dBjkk=" + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "varint": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.0.tgz", + "integrity": "sha1-2Ca4n3SQcy+rwMDtaT7Uddyynr8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } +} diff --git a/interop/js/package.json b/interop/js/package.json new file mode 100644 index 0000000..9970bb5 --- /dev/null +++ b/interop/js/package.json @@ -0,0 +1,14 @@ +{ + "name": "mplex-test", + "version": "1.0.0", + "description": "mplex test program", + "author": "", + "license": "ISC", + "dependencies": { + "interface-connection": "^0.3.2", + "libp2p-mplex": "^0.7.0", + "pull-stream": "^3.6.7", + "stream-to-pull-stream": "^1.7.2", + "tcp": "^1.0.0" + } +} diff --git a/interop/js/server.js b/interop/js/server.js new file mode 100644 index 0000000..f69a770 --- /dev/null +++ b/interop/js/server.js @@ -0,0 +1,51 @@ +const assert = require('assert') + +const mplex = require('libp2p-mplex') +const toPull = require('stream-to-pull-stream') +const pull = require('pull-stream') +const tcp = require('tcp') + +const jsTestData = 'test data from js' +const goTestData = 'test data from go' + +function readWrite (stream) { + pull( + stream, + pull.concat((err, data) => { + if (err) { + throw err + } + let offset = 0 + for (let i = 0; i < 100; i++) { + let expected = goTestData + ' ' + i + assert.equal(expected, data.slice(offset, offset + expected.length)) + offset += expected.length + } + }) + ) + pull( + pull.count(99), + pull.map((i) => jsTestData + ' ' + i), + stream + ) +} + +const listener = tcp.createServer((socket) => { + let muxer = mplex.listener(toPull(socket)) + muxer.on('stream', (stream) => { + readWrite(stream) + }) + for (let i = 0; i < 100; i++) { + muxer.newStream((err, stream) => { + if (err) { + throw err + } + readWrite(stream) + }) + } + socket.on('close', () => { + listener.close() + }) +}) + +listener.listen(9991) diff --git a/interop/test.sh b/interop/test.sh new file mode 100755 index 0000000..7f6ef9d --- /dev/null +++ b/interop/test.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +( + cd "js" + npm install +) + +( + cd "js" && npm start +) & + +sleep 1 + +( + cd "go" && go run main.go +) & + +wait