stats.js
1 import Client from '../index.js' 2 import commonTest from './common.js' 3 import fixtures from 'webtorrent-fixtures' 4 import fetch from 'cross-fetch-ponyfill' 5 import test from 'tape' 6 7 const peerId = Buffer.from('-WW0091-4ea5886ce160') 8 const unknownPeerId = Buffer.from('01234567890123456789') 9 10 function parseHtml (html) { 11 const extractValue = /[^v^h](\d+)/ 12 const array = html.replace('torrents', '\n').split('\n').filter(line => line && line.trim().length > 0).map(line => { 13 const a = extractValue.exec(line) 14 if (a) { 15 return parseInt(a[1]) 16 } 17 return null 18 }) 19 let i = 0 20 return { 21 torrents: array[i++], 22 activeTorrents: array[i++], 23 peersAll: array[i++], 24 peersSeederOnly: array[i++], 25 peersLeecherOnly: array[i++], 26 peersSeederAndLeecher: array[i++], 27 peersIPv4: array[i++], 28 peersIPv6: array[i] 29 } 30 } 31 32 test('server: get empty stats', t => { 33 t.plan(10) 34 35 commonTest.createServer(t, 'http', async (server, announceUrl) => { 36 const url = announceUrl.replace('/announce', '/stats') 37 38 let res 39 try { 40 res = await fetch(url) 41 } catch (err) { 42 t.error(err) 43 } 44 const data = Buffer.from(await res.arrayBuffer()) 45 46 const stats = parseHtml(data.toString()) 47 t.equal(res.status, 200) 48 t.equal(stats.torrents, 0) 49 t.equal(stats.activeTorrents, 0) 50 t.equal(stats.peersAll, 0) 51 t.equal(stats.peersSeederOnly, 0) 52 t.equal(stats.peersLeecherOnly, 0) 53 t.equal(stats.peersSeederAndLeecher, 0) 54 t.equal(stats.peersIPv4, 0) 55 t.equal(stats.peersIPv6, 0) 56 57 server.close(() => { t.pass('server closed') }) 58 }) 59 }) 60 61 test('server: get empty stats with json header', t => { 62 t.plan(10) 63 64 commonTest.createServer(t, 'http', async (server, announceUrl) => { 65 const opts = { 66 url: announceUrl.replace('/announce', '/stats'), 67 headers: { 68 accept: 'application/json' 69 } 70 } 71 let res 72 try { 73 res = await fetch(announceUrl.replace('/announce', '/stats'), opts) 74 } catch (err) { 75 t.error(err) 76 } 77 const stats = await res.json() 78 79 t.equal(res.status, 200) 80 t.equal(stats.torrents, 0) 81 t.equal(stats.activeTorrents, 0) 82 t.equal(stats.peersAll, 0) 83 t.equal(stats.peersSeederOnly, 0) 84 t.equal(stats.peersLeecherOnly, 0) 85 t.equal(stats.peersSeederAndLeecher, 0) 86 t.equal(stats.peersIPv4, 0) 87 t.equal(stats.peersIPv6, 0) 88 89 server.close(() => { t.pass('server closed') }) 90 }) 91 }) 92 93 test('server: get empty stats on stats.json', t => { 94 t.plan(10) 95 96 commonTest.createServer(t, 'http', async (server, announceUrl) => { 97 let res 98 try { 99 res = await fetch(announceUrl.replace('/announce', '/stats.json')) 100 } catch (err) { 101 t.error(err) 102 } 103 const stats = await res.json() 104 105 t.equal(res.status, 200) 106 t.equal(stats.torrents, 0) 107 t.equal(stats.activeTorrents, 0) 108 t.equal(stats.peersAll, 0) 109 t.equal(stats.peersSeederOnly, 0) 110 t.equal(stats.peersLeecherOnly, 0) 111 t.equal(stats.peersSeederAndLeecher, 0) 112 t.equal(stats.peersIPv4, 0) 113 t.equal(stats.peersIPv6, 0) 114 115 server.close(() => { t.pass('server closed') }) 116 }) 117 }) 118 119 test('server: get leecher stats.json', t => { 120 t.plan(10) 121 122 commonTest.createServer(t, 'http', (server, announceUrl) => { 123 // announce a torrent to the tracker 124 const client = new Client({ 125 infoHash: fixtures.leaves.parsedTorrent.infoHash, 126 announce: announceUrl, 127 peerId, 128 port: 6881 129 }) 130 client.on('error', err => { t.error(err) }) 131 client.on('warning', err => { t.error(err) }) 132 133 client.start() 134 135 server.once('start', async () => { 136 let res 137 try { 138 res = await fetch(announceUrl.replace('/announce', '/stats.json')) 139 } catch (err) { 140 t.error(err) 141 } 142 const stats = await res.json() 143 144 t.equal(res.status, 200) 145 t.equal(stats.torrents, 1) 146 t.equal(stats.activeTorrents, 1) 147 t.equal(stats.peersAll, 1) 148 t.equal(stats.peersSeederOnly, 0) 149 t.equal(stats.peersLeecherOnly, 1) 150 t.equal(stats.peersSeederAndLeecher, 0) 151 t.equal(stats.clients.WebTorrent['0.91'], 1) 152 153 client.destroy(() => { t.pass('client destroyed') }) 154 server.close(() => { t.pass('server closed') }) 155 }) 156 }) 157 }) 158 159 test('server: get leecher stats.json (unknown peerId)', t => { 160 t.plan(10) 161 162 commonTest.createServer(t, 'http', (server, announceUrl) => { 163 // announce a torrent to the tracker 164 const client = new Client({ 165 infoHash: fixtures.leaves.parsedTorrent.infoHash, 166 announce: announceUrl, 167 peerId: unknownPeerId, 168 port: 6881 169 }) 170 client.on('error', err => { t.error(err) }) 171 client.on('warning', err => { t.error(err) }) 172 173 client.start() 174 175 server.once('start', async () => { 176 let res 177 try { 178 res = await fetch(announceUrl.replace('/announce', '/stats.json')) 179 } catch (err) { 180 t.error(err) 181 } 182 const stats = await res.json() 183 184 t.equal(res.status, 200) 185 t.equal(stats.torrents, 1) 186 t.equal(stats.activeTorrents, 1) 187 t.equal(stats.peersAll, 1) 188 t.equal(stats.peersSeederOnly, 0) 189 t.equal(stats.peersLeecherOnly, 1) 190 t.equal(stats.peersSeederAndLeecher, 0) 191 t.equal(stats.clients.unknown['01234567'], 1) 192 193 client.destroy(() => { t.pass('client destroyed') }) 194 server.close(() => { t.pass('server closed') }) 195 }) 196 }) 197 })