Skip to content

Commit

Permalink
chore: move transport interface tests to integration package (#2813)
Browse files Browse the repository at this point in the history
Breaks sibling dependencies between interface tests and transports
which means a fix to the connection encrypter interface tests don't
cause a tcp release which causes a libp2p release which causes a
webrtc release.
  • Loading branch information
achingbrain authored Nov 7, 2024
1 parent 6657690 commit 32ca76f
Show file tree
Hide file tree
Showing 35 changed files with 803 additions and 1,030 deletions.
3 changes: 1 addition & 2 deletions packages/connection-encrypter-plaintext/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,9 @@
},
"devDependencies": {
"@libp2p/crypto": "^5.0.6",
"@libp2p/interface-compliance-tests": "^6.1.8",
"@libp2p/logger": "^5.1.3",
"@multiformats/multiaddr": "^12.2.3",
"aegir": "^44.0.1",
"it-pair": "^2.0.6",
"protons": "^7.5.0",
"sinon": "^18.0.0"
},
Expand Down
29 changes: 5 additions & 24 deletions packages/connection-encrypter-plaintext/test/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
/* eslint-env mocha */

import { generateKeyPair } from '@libp2p/crypto/keys'
import { mockMultiaddrConnPair } from '@libp2p/interface-compliance-tests/mocks'
import { defaultLogger } from '@libp2p/logger'
import { peerIdFromMultihash, peerIdFromPrivateKey } from '@libp2p/peer-id'
import { multiaddr } from '@multiformats/multiaddr'
import { peerIdFromPrivateKey } from '@libp2p/peer-id'
import { expect } from 'aegir/chai'
import { duplexPair } from 'it-pair/duplex'
import sinon from 'sinon'
import { plaintext } from '../src/index.js'
import type { ConnectionEncrypter, PeerId } from '@libp2p/interface'

describe('plaintext', () => {
let localPeer: PeerId
let remotePeer: PeerId
let wrongPeer: PeerId
let encrypter: ConnectionEncrypter
let encrypterRemote: ConnectionEncrypter

beforeEach(async () => {
[remotePeer, wrongPeer] = await Promise.all([
peerIdFromPrivateKey(await generateKeyPair('Ed25519')),
peerIdFromPrivateKey(await generateKeyPair('Ed25519'))
])
wrongPeer = peerIdFromPrivateKey(await generateKeyPair('Ed25519'))

const localKeyPair = await generateKeyPair('Ed25519')
localPeer = peerIdFromPrivateKey(localKeyPair)
Expand All @@ -41,13 +36,7 @@ describe('plaintext', () => {
})

it('should verify the public key and id match', async () => {
const { inbound, outbound } = mockMultiaddrConnPair({
remotePeer,
addrs: [
multiaddr('/ip4/127.0.0.1/tcp/1234'),
multiaddr('/ip4/127.0.0.1/tcp/1235')
]
})
const [inbound, outbound] = duplexPair<any>()

await Promise.all([
encrypter.secureInbound(inbound),
Expand All @@ -62,21 +51,13 @@ describe('plaintext', () => {

it('should fail if the peer does not provide its public key', async () => {
const keyPair = await generateKeyPair('RSA', 512)
const peer = peerIdFromPrivateKey(keyPair)
remotePeer = peerIdFromMultihash(peer.toMultihash())

encrypter = plaintext()({
privateKey: keyPair,
logger: defaultLogger()
})

const { inbound, outbound } = mockMultiaddrConnPair({
remotePeer,
addrs: [
multiaddr('/ip4/127.0.0.1/tcp/1234'),
multiaddr('/ip4/127.0.0.1/tcp/1235')
]
})
const [inbound, outbound] = duplexPair<any>()

await expect(Promise.all([
encrypter.secureInbound(inbound),
Expand Down
6 changes: 4 additions & 2 deletions packages/connection-encrypter-tls/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@
"uint8arrays": "^5.1.0"
},
"devDependencies": {
"@libp2p/interface-compliance-tests": "^6.1.8",
"@libp2p/logger": "^5.1.3",
"@multiformats/multiaddr": "^12.2.3",
"aegir": "^44.0.1",
"it-pair": "^2.0.6",
"protons": "^7.5.0",
"sinon": "^18.0.0"
},
"browser": {
"./dist/src/tls.js": "./dist/src/tls.browser.js"
},
"sideEffects": false
}
27 changes: 27 additions & 0 deletions packages/connection-encrypter-tls/src/tls.browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { serviceCapabilities } from '@libp2p/interface'
import { PROTOCOL } from './index.js'
import type { MultiaddrConnection, ConnectionEncrypter, SecuredConnection, SecureConnectionOptions } from '@libp2p/interface'
import type { Duplex } from 'it-stream-types'
import type { Uint8ArrayList } from 'uint8arraylist'

export class TLS implements ConnectionEncrypter {
public protocol: string = PROTOCOL

constructor () {
throw new Error('TLS encryption is not possible in browsers')
}

readonly [Symbol.toStringTag] = '@libp2p/tls'

readonly [serviceCapabilities]: string[] = [
'@libp2p/connection-encryption'
]

async secureInbound <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (conn: Stream, options?: SecureConnectionOptions): Promise<SecuredConnection<Stream>> {
throw new Error('TLS encryption is not possible in browsers')
}

async secureOutbound <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (conn: Stream, options?: SecureConnectionOptions): Promise<SecuredConnection<Stream>> {
throw new Error('TLS encryption is not possible in browsers')
}
}
19 changes: 3 additions & 16 deletions packages/connection-encrypter-tls/test/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
/* eslint-env mocha */

import { generateKeyPair } from '@libp2p/crypto/keys'
import { mockMultiaddrConnPair } from '@libp2p/interface-compliance-tests/mocks'
import { defaultLogger } from '@libp2p/logger'
import { peerIdFromMultihash, peerIdFromPrivateKey } from '@libp2p/peer-id'
import { multiaddr } from '@multiformats/multiaddr'
import { expect } from 'aegir/chai'
import { duplexPair } from 'it-pair/duplex'
import sinon from 'sinon'
import { tls } from '../src/index.js'
import type { ConnectionEncrypter, PeerId } from '@libp2p/interface'
Expand Down Expand Up @@ -36,13 +35,7 @@ describe('tls', () => {
})

it('should verify the public key and id match', async () => {
const { inbound, outbound } = mockMultiaddrConnPair({
remotePeer,
addrs: [
multiaddr('/ip4/127.0.0.1/tcp/1234'),
multiaddr('/ip4/127.0.0.1/tcp/1235')
]
})
const [inbound, outbound] = duplexPair<any>()

await Promise.all([
encrypter.secureInbound(inbound, {
Expand All @@ -67,13 +60,7 @@ describe('tls', () => {
logger: defaultLogger()
})

const { inbound, outbound } = mockMultiaddrConnPair({
remotePeer,
addrs: [
multiaddr('/ip4/127.0.0.1/tcp/1234'),
multiaddr('/ip4/127.0.0.1/tcp/1235')
]
})
const [inbound, outbound] = duplexPair<any>()

await expect(Promise.all([
encrypter.secureInbound(inbound, {
Expand Down
16 changes: 12 additions & 4 deletions packages/integration-tests/.aegir.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,21 @@ export default {
const { mplex } = await import('@libp2p/mplex')
const { noise } = await import('@chainsafe/libp2p-noise')
const { yamux } = await import('@chainsafe/libp2p-yamux')
const { WebSockets } = await import('@multiformats/mafmt')
const { WebSockets } = await import('@multiformats/multiaddr-matcher')
const { createLibp2p } = await import('libp2p')
const { plaintext } = await import('@libp2p/plaintext')
const { circuitRelayServer, circuitRelayTransport } = await import('@libp2p/circuit-relay-v2')
const { identify } = await import('@libp2p/identify')
const { echo } = await import('@libp2p/echo')
const { mockMuxer } = await import('@libp2p/interface-compliance-tests/mocks')

const libp2p = await createLibp2p({
connectionManager: {
inboundConnectionThreshold: Infinity
},
addresses: {
listen: [
'/ip4/127.0.0.1/tcp/0/ws',
'/ip4/127.0.0.1/tcp/0/ws'
]
},
Expand All @@ -35,7 +37,8 @@ export default {
],
streamMuxers: [
yamux(),
mplex()
mplex(),
() => mockMuxer()
],
connectionEncrypters: [
noise(),
Expand All @@ -48,17 +51,22 @@ export default {
maxReservations: Infinity
}
}),
echo: echo()
echo: echo({
maxInboundStreams: 5
})
}
})

const goLibp2pRelay = await createGoLibp2pRelay()
const wsAddresses = libp2p.getMultiaddrs().filter(ma => WebSockets.exactMatch(ma))

return {
libp2p,
goLibp2pRelay,
env: {
RELAY_MULTIADDR: libp2p.getMultiaddrs().filter(ma => WebSockets.matches(ma)).pop(),
RELAY_MULTIADDR: wsAddresses[0],
RELAY_WS_MULTIADDR_0: wsAddresses[0],
RELAY_WS_MULTIADDR_1: wsAddresses[1],
GO_RELAY_PEER: goLibp2pRelay.peerId,
GO_RELAY_MULTIADDRS: goLibp2pRelay.multiaddrs,
GO_RELAY_APIADDR: goLibp2pRelay.apiAddr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import { generateKeyPair } from '@libp2p/crypto/keys'
import suite from '@libp2p/interface-compliance-tests/connection-encryption'
import { defaultLogger } from '@libp2p/logger'
import { plaintext } from '../src/index.js'
import { plaintext } from '@libp2p/plaintext'

describe('plaintext compliance', () => {
describe('plaintext connection encrypter interface compliance', () => {
suite({
async setup (opts) {
return plaintext()({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
import { generateKeyPair } from '@libp2p/crypto/keys'
import suite from '@libp2p/interface-compliance-tests/connection-encryption'
import { defaultLogger } from '@libp2p/logger'
import { tls } from '../src/index.js'
import { tls } from '@libp2p/tls'
import { isBrowser, isWebWorker } from 'wherearewe'

describe('tls connection encrypter interface compliance', () => {
if (isBrowser || isWebWorker) {
return
}

describe('tls compliance', () => {
suite({
async setup (opts) {
return tls()({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import tests from '@libp2p/interface-compliance-tests/transport'
import { memory } from '@libp2p/memory'
import { multiaddr } from '@multiformats/multiaddr'
import type { Multiaddr } from '@multiformats/multiaddr'

describe('memory transport interface compliance tests', () => {
tests({
async setup () {
const transport = memory()
const dialAddrs: [Multiaddr, Multiaddr] = [
multiaddr('/memory/addr-1'),
multiaddr('/memory/addr-2')
]

return { transport, dialAddrs }
},
async teardown () {}
})
})
43 changes: 43 additions & 0 deletions packages/integration-tests/test/compliance/transport/tcp.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import tests from '@libp2p/interface-compliance-tests/transport'
import { tcp } from '@libp2p/tcp'
import { multiaddr } from '@multiformats/multiaddr'
import { isBrowser, isWebWorker } from 'wherearewe'
import type { Multiaddr } from '@multiformats/multiaddr'

describe('tcp transport interface compliance IPv4', () => {
if (isBrowser || isWebWorker) {
return
}

tests({
async setup () {
const transport = tcp()
const dialAddrs: [Multiaddr, Multiaddr] = [
multiaddr('/ip4/127.0.0.1/tcp/9091'),
multiaddr('/ip4/127.0.0.1/tcp/9092')
]

return { transport, dialAddrs }
},
async teardown () {}
})
})

describe('tcp transport interface compliance IPv6', () => {
if (isBrowser || isWebWorker) {
return
}

tests({
async setup () {
const transport = tcp()
const dialAddrs: [Multiaddr, Multiaddr] = [
multiaddr('/ip6/::/tcp/9093'),
multiaddr('/ip6/::/tcp/9094')
]

return { transport, dialAddrs }
},
async teardown () {}
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* eslint-env mocha */

import tests from '@libp2p/interface-compliance-tests/transport'
import { webSockets } from '@libp2p/websockets'
import * as filters from '@libp2p/websockets/filters'
import { multiaddr } from '@multiformats/multiaddr'
import { isElectronMain, isNode } from 'wherearewe'
import type { Multiaddr } from '@multiformats/multiaddr'

describe('websocket transport interface compliance', () => {
tests({
async setup () {
const dialOnly = !isNode && !isElectronMain

const transport = webSockets({ filter: filters.all })
let dialAddrs: [Multiaddr, Multiaddr] = [
multiaddr('/ip4/127.0.0.1/tcp/9096/ws'),
multiaddr('/ip4/127.0.0.1/tcp/9097/ws')
]

if (dialOnly) {
dialAddrs = [
multiaddr(process.env.RELAY_WS_MULTIADDR_0),
multiaddr(process.env.RELAY_WS_MULTIADDR_1)
]
}

return {
transport,
listenAddrs: dialOnly ? undefined : dialAddrs,
dialAddrs,
dialOnly
}
},
async teardown () {}
})
})
11 changes: 9 additions & 2 deletions packages/integration-tests/test/fixtures/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,20 @@ export async function hasRelay (node: Libp2p, opts?: PWaitForOptions<PeerId>): P

// Wait for peer to be used as a relay
await pWaitFor(() => {
const relayAddrs = node.getMultiaddrs().filter(addr => addr.protoNames().includes('p2p-circuit'))
const relayHosts = new Set<string>()

const relayAddrs = node.getMultiaddrs().filter(addr => {
const options = addr.toOptions()
relayHosts.add(options.host)

return addr.protoNames().includes('p2p-circuit')
})

if (relayAddrs.length === 0) {
return false
}

if (relayAddrs.length !== 1) {
if (relayHosts.size !== 1) {
throw new Error(`node listening on too many relays - ${relayAddrs.length}`)
}

Expand Down
Loading

0 comments on commit 32ca76f

Please sign in to comment.