86 lines
3.9 KiB
Python
86 lines
3.9 KiB
Python
import json
|
|
from pathlib import Path
|
|
import tempfile
|
|
import unittest
|
|
from unittest.mock import patch
|
|
import urllib.error
|
|
from monitor import APIError, Client, connect, tick, validate
|
|
|
|
|
|
class MonitorTest(unittest.TestCase):
|
|
def test_transport_rate_limit_and_budget(self):
|
|
c = Client()
|
|
error = urllib.error.HTTPError('https://api.github.com', 429, 'limited', {'Retry-After': '7200'}, None)
|
|
with patch('urllib.request.urlopen', side_effect=error) as transport:
|
|
with self.assertRaises(APIError) as result:
|
|
c.get('https://api.github.com/repos/expressjs/express')
|
|
self.assertEqual(result.exception.retry, 7200)
|
|
c.calls = 24
|
|
with self.assertRaisesRegex(APIError, 'budget'):
|
|
c.get('https://api.github.com/repos/expressjs/express')
|
|
self.assertEqual(transport.call_count, 1)
|
|
|
|
def test_durable_delta_errors_and_optout(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
path = Path(tmp)
|
|
reg = json.loads(Path(__file__).with_name('registry.json').read_text())
|
|
calls = []
|
|
version = ['1.0.0']
|
|
fail = [False]
|
|
def get(url, body=None):
|
|
calls.append(url)
|
|
if fail[0]:
|
|
raise APIError('Upstream HTTP 429; coverage unknown', 7200)
|
|
if '/commits/' in url:
|
|
return {'sha': 'a'*40}
|
|
if '/releases?' in url:
|
|
return []
|
|
if 'raw.githubusercontent' in url:
|
|
return {'dependencies': {'example': '^1.0.0'}}
|
|
if 'registry.npmjs' in url:
|
|
return {'dist-tags': {'latest': version[0]}}
|
|
return {'private': False, 'default_branch': 'main'}
|
|
db = connect(path/'state.db')
|
|
out = tick(reg, db, path/'public.json', get, 100000)
|
|
self.assertEqual(out['repos'][0]['scan_status'], 'complete')
|
|
self.assertFalse(out['repos'][0]['diff'])
|
|
db.close() # new process/connection retains baseline and next due
|
|
db = connect(path/'state.db')
|
|
calls.clear()
|
|
tick(reg, db, path/'public.json', get, 100001)
|
|
self.assertEqual(calls, [])
|
|
version[0] = '2.0.0'
|
|
out = tick(reg, db, path/'public.json', get, 200000)
|
|
self.assertEqual(out['repos'][0]['diff'][0]['component'], 'npm:example')
|
|
self.assertEqual(len(out['repos'][0]['alerts']), 1)
|
|
fail[0] = True
|
|
out = tick(reg, db, path/'public.json', get, 300000)
|
|
self.assertEqual(out['repos'][0]['scan_status'], 'unknown')
|
|
self.assertEqual(out['repos'][0]['next_due'], 307200)
|
|
self.assertEqual(out['repos'][0]['last_success'], 200000)
|
|
self.assertEqual(db.execute('SELECT count(*) FROM snapshots').fetchone()[0], 2)
|
|
calls.clear()
|
|
reg['repos'][0]['state'] = 'paused'
|
|
out = tick(reg, db, path/'public.json', get, 400000)
|
|
self.assertEqual(calls, [])
|
|
self.assertFalse(out['repos'][0]['alerts'])
|
|
self.assertIsNone(out['repos'][0]['next_due'])
|
|
reg['repos'][0]['state'] = 'requested'
|
|
tick(reg, db, path/'public.json', get, 400001)
|
|
self.assertEqual(calls, [])
|
|
reg['repos'][0]['state'] = 'active'
|
|
reg['repos'][0]['notification'] = 'none'
|
|
fail[0] = False
|
|
version[0] = '3.0.0'
|
|
out = tick(reg, db, path/'public.json', get, 500000)
|
|
self.assertFalse(out['repos'][0]['alerts'])
|
|
self.assertEqual(db.execute('SELECT count(*) FROM alerts').fetchone()[0], 1)
|
|
reg['repos'][0]['public_consent'] = False
|
|
with self.assertRaises(ValueError):
|
|
validate(reg)
|
|
db.close()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|