/ test / stats.js
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  })