UpToDate: durable schedule installer and transport rate-limit acceptance
This commit is contained in:
1 parent
c3add0a8b0
commit
8b4f44c701
2 files changed
+39
-1
No files matched your search
@@ -0,0 +1,21 @@
|
||||
"""Install only this pilot's user LaunchAgent, after reviewed files are synced."""
|
||||
import os
|
||||
from pathlib import Path
|
||||
import plistlib
|
||||
import subprocess
|
||||
|
||||
home = Path.home()
|
||||
root = home / 'claude/up-to-date'
|
||||
logs = home / 'claude/logs/up-to-date'
|
||||
site = home / 'sites/notplanned/v/up-to-date'
|
||||
assert (root / 'monitor.py').is_file() and (root / 'registry.json').is_file()
|
||||
logs.mkdir(parents=True, exist_ok=True)
|
||||
target = home / 'Library/LaunchAgents/xyz.teahub.up-to-date.plist'
|
||||
assert not target.exists(), 'Reconcile existing schedule before replacing it'
|
||||
config = {'Label': 'xyz.teahub.up-to-date', 'StartInterval': 900, 'RunAtLoad': True,
|
||||
'ProgramArguments': ['/usr/bin/python3', str(root / 'monitor.py'), '--registry', str(root / 'registry.json'),
|
||||
'--state-dir', str(logs), '--public', str(site / 'monitor-status.json')],
|
||||
'StandardOutPath': str(logs / 'scan.log'), 'StandardErrorPath': str(logs / 'scan.log')}
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
target.write_bytes(plistlib.dumps(config))
|
||||
subprocess.run(['launchctl', 'bootstrap', 'gui/' + str(os.getuid()), str(target)], check=True)
|
||||
@@ -2,10 +2,24 @@ import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
from monitor import APIError, connect, tick, validate
|
||||
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)
|
||||
@@ -51,6 +65,9 @@ class MonitorTest(unittest.TestCase):
|
||||
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
|
||||
|
||||
Reference in new issue
Block a user