def test_connection_timeout_with_build(mock_systemd, slave_thread, mock_slave_driver, caplog): with mock.patch('piwheels.slave.builder.Popen') as popen_mock, \ mock.patch('piwheels.slave.time') as time_mock: time_mock.side_effect = cycle([1.0]) slave_thread.start() assert mock_systemd._ready.wait(10) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'HELLO' mock_slave_driver.send_addr_msg(addr, 'ACK', [1, 'https://pypi.org/pypi']) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'IDLE' mock_slave_driver.send_addr_msg(addr, 'BUILD', ['foo', '1.0']) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BUILT' time_mock.side_effect = chain([400.0], cycle([800.0])) # Allow timeout (time_mock takes care of faking this) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'HELLO' mock_slave_driver.send_addr_msg(addr, 'DIE') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BYE' slave_thread.join(10) assert not slave_thread.is_alive() assert find_message(caplog.records, message='Build failed') assert find_message(caplog.records, message='Timed out waiting for master')
def test_init_debug(db, with_clean_db, db_super_url, caplog): assert main( ['--dsn', db_super_url, '--user', PIWHEELS_USER, '--yes', '--debug']) == 0 with db.begin(): for row in db.execute("SELECT version FROM configuration"): assert row[0] == __version__ break else: assert False, "Didn't find version row in configuration" assert find_message(caplog.records, message='Initializing database at version %s' % __version__) assert find_message( caplog.records, message='REVOKE ALL PRIVILEGES ON SCHEMA public FROM PUBLIC;') assert find_message( caplog.records, message='REVOKE ALL PRIVILEGES ON SCHEMA public FROM PUBLIC;') assert find_message( caplog.records, message= 'CREATE INDEX builds_timestamp ON builds(built_at DESC NULLS LAST);') assert find_message( caplog.records, message='CREATE INDEX files_builds ON files(build_id);')
def test_slave_build_stop_failed(mock_systemd, slave_thread, mock_slave_driver, caplog): with mock.patch('piwheels.slave.Builder') as builder_mock: builder_mock().is_alive.return_value = True slave_thread.start() assert mock_systemd._ready.wait(10) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'HELLO' mock_slave_driver.send_addr_msg(addr, 'ACK', [1, 'https://pypi.org/pypi']) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'IDLE' mock_slave_driver.send_addr_msg(addr, 'BUILD', ['foo', '1.0']) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BUSY' mock_slave_driver.send_addr_msg(addr, 'CONT') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BUSY' mock_slave_driver.send_addr_msg(addr, 'DONE') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BYE' slave_thread.join(10) assert not slave_thread.is_alive() assert find_message(caplog.records, message='Terminating current build') assert find_message(caplog.records, message='Build failed to terminate')
def test_connection_timeout_with_build(mock_systemd, slave_thread, mock_slave_driver, caplog): with mock.patch('piwheels.slave.builder.Popen') as popen_mock, \ mock.patch('piwheels.slave.time') as time_mock: time_mock.side_effect = cycle([1.0]) slave_thread.start() assert mock_systemd._ready.wait(10) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data)[0] == 'HELLO' mock_slave_driver.send_multipart( [addr, sep, pickle.dumps(['HELLO', 1, 'https://pypi.org/pypi'])]) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data) == ['IDLE'] mock_slave_driver.send_multipart( [addr, sep, pickle.dumps(['BUILD', 'foo', '1.0'])]) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data)[0] == 'BUILT' time_mock.side_effect = chain([400.0], cycle([800.0])) # Allow timeout (time_mock takes care of faking this) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data)[0] == 'HELLO' mock_slave_driver.send_multipart([addr, sep, pickle.dumps(['BYE'])]) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data) == ['BYE'] slave_thread.join(10) assert not slave_thread.is_alive() assert find_message(caplog.records, 'Build failed') assert find_message(caplog.records, 'Timed out waiting for master')
def test_pause_resume(mock_systemd, master_thread, master_control, caplog): master_thread.start() assert mock_systemd._ready.wait(10) master_control.send_pyobj(['PAUSE']) master_control.send_pyobj(['RESUME']) master_control.send_pyobj(['QUIT']) master_thread.join(10) assert not master_thread.is_alive() assert find_message(caplog.records, 'pausing operations') assert find_message(caplog.records, 'resuming operations')
def test_pause_resume(mock_systemd, master_thread, master_control, caplog): thread = master_thread() thread.start() assert mock_systemd._ready.wait(10) master_control.send_msg('PAUSE') master_control.send_msg('RESUME') master_control.send_msg('QUIT') thread.join(10) assert not thread.is_alive() assert find_message(caplog.records, message='pausing operations') assert find_message(caplog.records, message='resuming operations')
def test_debug(mock_systemd, master_thread, master_control, caplog): thread = master_thread(args=['--debug', 'master.the_scribe', '--debug', 'master.the_architect']) thread.start() assert mock_systemd._ready.wait(10) master_control.send_msg('QUIT') thread.join(10) assert not thread.is_alive() assert find_message(caplog.records, name='master.the_scribe', levelname='DEBUG', message='<< QUIT None') assert find_message(caplog.records, name='master.the_architect', levelname='DEBUG', message='<< QUIT None')
def test_sleep_all_control(mock_systemd, master_thread, master_control, caplog): thread = master_thread() thread.start() assert mock_systemd._ready.wait(10) master_control.send_msg('SLEEP', None) master_control.send_msg('WAKE', None) master_control.send_msg('QUIT') thread.join(10) assert not thread.is_alive() assert find_message(caplog.records, message='sleeping all slaves and master') assert find_message(caplog.records, message='waking all slaves and master')
def test_slave_build_send_done(mock_systemd, slave_thread, mock_slave_driver, tmpdir, caplog): with mock.patch('piwheels.slave.builder.Popen') as popen_mock, \ mock.patch('piwheels.slave.builder.PiWheelsPackage.transfer') as transfer_mock, \ mock.patch('piwheels.slave.builder.tempfile.TemporaryDirectory') as tmpdir_mock: popen_mock().returncode = 0 tmpdir_mock().name = str(tmpdir) tmpdir.join('foo-0.1-cp34-cp34m-linux_armv7l.whl').ensure() slave_thread.start() assert mock_systemd._ready.wait(10) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data)[0] == 'HELLO' mock_slave_driver.send_multipart( [addr, sep, pickle.dumps(['HELLO', 1, 'https://pypi.org/pypi'])]) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data) == ['IDLE'] mock_slave_driver.send_multipart( [addr, sep, pickle.dumps(['BUILD', 'foo', '1.0'])]) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data)[0] == 'BUILT' assert popen_mock.call_args == mock.call([ 'pip3', 'wheel', '--index-url=https://pypi.org/pypi', mock.ANY, mock.ANY, '--no-deps', '--no-cache-dir', '--exists-action=w', '--disable-pip-version-check', 'foo==1.0' ], stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL, env=mock.ANY) mock_slave_driver.send_multipart([ addr, sep, pickle.dumps(['SEND', 'foo-0.1-cp34-cp34m-linux_armv7l.whl']) ]) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data) == ['SENT'] mock_slave_driver.send_multipart([addr, sep, pickle.dumps(['DONE'])]) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data) == ['IDLE'] mock_slave_driver.send_multipart([addr, sep, pickle.dumps(['BYE'])]) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data) == ['BYE'] slave_thread.join(10) assert not slave_thread.is_alive() assert find_message(caplog.records, 'Build succeeded') assert find_message( caplog.records, 'Sending foo-0.1-cp34-cp34m-linux_armv7l.whl to master on localhost') assert find_message(caplog.records, 'Removing temporary build directories')
def test_slave_build_send_done(mock_systemd, slave_thread, mock_slave_driver, tmpdir, caplog): with mock.patch('piwheels.slave.builder.Popen') as popen_mock, \ mock.patch('piwheels.slave.builder.PiWheelsPackage._calculate_apt_dependencies') as apt_mock, \ mock.patch('piwheels.slave.builder.PiWheelsPackage.transfer') as transfer_mock, \ mock.patch('piwheels.slave.builder.tempfile.TemporaryDirectory') as tmpdir_mock: popen_mock().returncode = 0 apt_mock.return_value = {} tmpdir_mock().name = str(tmpdir) tmpdir.join('foo-0.1-cp34-cp34m-linux_armv7l.whl').ensure() slave_thread.start() assert mock_systemd._ready.wait(10) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'HELLO' mock_slave_driver.send_addr_msg(addr, 'ACK', [1, 'https://pypi.org/pypi']) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'IDLE' mock_slave_driver.send_addr_msg(addr, 'BUILD', ['foo', '1.0']) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BUILT' assert popen_mock.call_args == mock.call([ 'pip3', 'wheel', '--index-url=https://pypi.org/pypi', mock.ANY, mock.ANY, '--no-deps', '--no-cache-dir', '--exists-action=w', '--disable-pip-version-check', 'foo==1.0' ], stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL, env=mock.ANY) mock_slave_driver.send_addr_msg(addr, 'SEND', 'foo-0.1-cp34-cp34m-linux_armv7l.whl') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'SENT' mock_slave_driver.send_addr_msg(addr, 'DONE') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'IDLE' mock_slave_driver.send_addr_msg(addr, 'DIE') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BYE' slave_thread.join(10) assert not slave_thread.is_alive() assert find_message(caplog.records, message='Build succeeded') assert find_message(caplog.records, message='Sending foo-0.1-cp34-cp34m-linux_armv7l.whl ' 'to master on localhost') assert find_message(caplog.records, message='Removing temporary build directories')
def test_no_root(caplog): main = PiWheelsSlave() with mock.patch('os.geteuid') as geteuid: geteuid.return_value = 0 assert main([]) != 0 assert find_message(caplog.records, message='Slave must not be run as root')
def test_slave_build_failed(mock_systemd, slave_thread, mock_slave_driver, caplog): with mock.patch('piwheels.slave.builder.Popen') as popen_mock: popen_mock().returncode = 1 slave_thread.start() assert mock_systemd._ready.wait(10) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data)[0] == 'HELLO' mock_slave_driver.send_multipart( [addr, sep, pickle.dumps(['HELLO', 1, 'https://pypi.org/pypi'])]) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data) == ['IDLE'] mock_slave_driver.send_multipart( [addr, sep, pickle.dumps(['BUILD', 'foo', '1.0'])]) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data)[0] == 'BUILT' assert popen_mock.call_args == mock.call([ 'pip3', 'wheel', '--index-url=https://pypi.org/pypi', mock.ANY, mock.ANY, '--no-deps', '--no-cache-dir', '--exists-action=w', '--disable-pip-version-check', 'foo==1.0' ], stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL, env=mock.ANY) mock_slave_driver.send_multipart([addr, sep, pickle.dumps(['BYE'])]) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data) == ['BYE'] slave_thread.join(10) assert not slave_thread.is_alive() assert find_message(caplog.records, 'Build failed')
def test_connection_timeout(mock_systemd, slave_thread, mock_slave_driver, caplog): with mock.patch('piwheels.slave.datetime') as time_mock: start = datetime.now(tz=UTC) time_mock.side_effect = datetime time_mock.now.side_effect = chain([ start, start, start + timedelta(seconds=400), start + timedelta(seconds=401), ], cycle([ start + timedelta(seconds=403), ])) slave_thread.start() assert mock_systemd._ready.wait(10) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'HELLO' # Allow timeout (time_mock takes care of faking this) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'HELLO' mock_slave_driver.send_addr_msg(addr, 'DIE') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BYE' slave_thread.join(10) assert not slave_thread.is_alive() assert find_message(caplog.records, message='Timed out waiting for master')
def test_slave_build_failed(mock_systemd, slave_thread, mock_slave_driver, caplog): with mock.patch('piwheels.slave.builder.Popen') as popen_mock: popen_mock().returncode = 1 slave_thread.start() assert mock_systemd._ready.wait(10) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'HELLO' mock_slave_driver.send_addr_msg(addr, 'ACK', [1, 'https://pypi.org/pypi']) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'IDLE' mock_slave_driver.send_addr_msg(addr, 'BUILD', ['foo', '1.0']) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BUILT' assert popen_mock.call_args == mock.call([ 'pip3', 'wheel', '--index-url=https://pypi.org/pypi', mock.ANY, mock.ANY, '--no-deps', '--no-cache-dir', '--no-binary=:all:', '--exists-action=w', '--disable-pip-version-check', 'foo==1.0'], stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL, env=mock.ANY ) mock_slave_driver.send_addr_msg(addr, 'DIE') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BYE' slave_thread.join(10) assert not slave_thread.is_alive() assert find_message(caplog.records, message='Build failed')
def test_bad_clock(caplog): main = PiWheelsSlave() with mock.patch('piwheels.slave.datetime') as dt: dt.side_effect = datetime dt.now.return_value = datetime(2000, 1, 1, tzinfo=timezone.utc) assert main([]) != 0 assert find_message(caplog.records, message='System clock is far in the past')
def test_bad_control(mock_systemd, master_thread, master_control, caplog): master_thread.start() assert mock_systemd._ready.wait(10) master_control.send_pyobj(['FOO']) master_control.send_pyobj(['QUIT']) master_thread.join(10) assert not master_thread.is_alive() assert find_message(caplog.records, 'ignoring invalid FOO message')
def test_system_ctrl_c(mock_systemd, master_thread, caplog): with mock.patch('piwheels.master.PiWheelsMaster.main_loop') as main_loop: main_loop.side_effect = KeyboardInterrupt() master_thread.start() assert mock_systemd._ready.wait(10) master_thread.join(10) assert not master_thread.is_alive() assert find_message(caplog.records, 'shutting down on Ctrl+C')
def test_system_exit(mock_systemd, master_thread, caplog): with mock.patch('piwheels.master.PiWheelsMaster.main_loop') as main_loop: main_loop.side_effect = SystemExit(1) master_thread.start() assert mock_systemd._ready.wait(10) master_thread.join(10) assert not master_thread.is_alive() assert find_message(caplog.records, 'shutting down on SIGTERM')
def test_bad_control(mock_systemd, master_thread, master_control, caplog): thread = master_thread() thread.start() assert mock_systemd._ready.wait(10) master_control.send(b'FOO') master_control.send_msg('QUIT') thread.join(10) assert not thread.is_alive() assert find_message(caplog.records, message='unable to deserialize data')
def test_slave_build_send_done(mock_systemd, slave_thread, mock_slave_driver, file_state, tmpdir, caplog): with mock.patch('piwheels.slave.Builder') as builder_mock: builder_mock().is_alive.return_value = False builder_mock().as_message.return_value = [ 'foo', '1.0', True, timedelta(seconds=6), '', [tuple(file_state)[:-1]] ] wheel_mock = mock.Mock() wheel_mock.filename = file_state.filename builder_mock().wheels = [wheel_mock] builder_mock().status = True slave_thread.start() assert mock_systemd._ready.wait(10) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'HELLO' mock_slave_driver.send_addr_msg(addr, 'ACK', [1, 'https://pypi.org/pypi']) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'IDLE' mock_slave_driver.send_addr_msg(addr, 'BUILD', ['foo', '1.0']) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BUSY' mock_slave_driver.send_addr_msg(addr, 'CONT') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BUILT' mock_slave_driver.send_addr_msg(addr, 'SEND', 'foo-0.1-cp34-cp34m-linux_armv7l.whl') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'SENT' mock_slave_driver.send_addr_msg(addr, 'DONE') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'IDLE' mock_slave_driver.send_addr_msg(addr, 'DIE') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BYE' slave_thread.join(10) assert not slave_thread.is_alive() assert find_message(caplog.records, message='Build succeeded') assert find_message(caplog.records, message='Sending foo-0.1-cp34-cp34m-linux_armv7l.whl ' 'to master on localhost') assert find_message(caplog.records, message='Removing temporary build directories')
def test_new_monitor(mock_systemd, master_thread, master_control, caplog): with mock.patch('piwheels.master.SlaveDriver.list_slaves') as list_slaves: master_thread.start() assert mock_systemd._ready.wait(10) master_control.send_pyobj(['HELLO']) master_control.send_pyobj(['QUIT']) master_thread.join(10) assert not master_thread.is_alive() assert find_message(caplog.records, 'sending status to new monitor') assert list_slaves.call_args == mock.call()
def test_init(db, with_clean_db, db_super_url, caplog): assert main(['--dsn', db_super_url, '--user', PIWHEELS_USER, '--yes']) == 0 with db.begin(): for row in db.execute("SELECT version FROM configuration"): assert row[0] == __version__ break else: assert False, "Didn't find version row in configuration" assert find_message(caplog.records, 'Initializing database at version %s' % __version__)
def test_skip_all_control(mock_systemd, master_thread, master_control, caplog): with mock.patch('piwheels.master.SlaveDriver.skip_slave') as skip_slave: thread = master_thread() thread.start() assert mock_systemd._ready.wait(10) master_control.send_msg('SKIP', None) master_control.send_msg('QUIT') thread.join(10) assert not thread.is_alive() assert skip_slave.call_args == mock.call(None) assert find_message(caplog.records, message='skipping all slaves')
def test_connection_timeout_with_build(mock_systemd, slave_thread, mock_slave_driver, caplog): with mock.patch('piwheels.slave.datetime') as time_mock, \ mock.patch('piwheels.slave.Builder') as builder_mock: builder_mock().is_alive.return_value = False builder_mock().status = False start = datetime.now(tz=UTC) time_mock.side_effect = datetime time_mock.now.side_effect = cycle([start]) slave_thread.start() assert mock_systemd._ready.wait(10) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'HELLO' mock_slave_driver.send_addr_msg(addr, 'ACK', [1, 'https://pypi.org/pypi']) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'IDLE' mock_slave_driver.send_addr_msg(addr, 'BUILD', ['foo', '1.0']) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BUSY' time_mock.now.side_effect = chain([ start + timedelta(seconds=400), ], cycle([ start + timedelta(seconds=800), ])) # Allow timeout (time_mock takes care of faking this) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'HELLO' mock_slave_driver.send_addr_msg(addr, 'DIE') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BYE' slave_thread.join(10) assert not slave_thread.is_alive() assert find_message(caplog.records, message='Removing temporary build directories') assert find_message(caplog.records, message='Timed out waiting for master')
def test_connection_timeout(mock_systemd, slave_thread, mock_slave_driver, caplog): with mock.patch('piwheels.slave.time') as time_mock: time_mock.side_effect = chain([1.0, 401.0, 402.0], cycle([403.0])) slave_thread.start() assert mock_systemd._ready.wait(10) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'HELLO' # Allow timeout (time_mock takes care of faking this) addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'HELLO' mock_slave_driver.send_addr_msg(addr, 'DIE') addr, msg, data = mock_slave_driver.recv_addr_msg() assert msg == 'BYE' slave_thread.join(10) assert not slave_thread.is_alive() assert find_message(caplog.records, message='Timed out waiting for master')
def test_connection_timeout(mock_systemd, slave_thread, mock_slave_driver, caplog): with mock.patch('piwheels.slave.time') as time_mock: time_mock.side_effect = chain([1.0, 401.0, 402.0], cycle([403.0])) slave_thread.start() assert mock_systemd._ready.wait(10) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data)[0] == 'HELLO' # Allow timeout (time_mock takes care of faking this) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data)[0] == 'HELLO' mock_slave_driver.send_multipart([addr, sep, pickle.dumps(['BYE'])]) addr, sep, data = mock_slave_driver.recv_multipart() assert pickle.loads(data) == ['BYE'] slave_thread.join(10) assert not slave_thread.is_alive() assert find_message(caplog.records, 'Timed out waiting for master')
def test_full_upgrade(db, with_clean_db, db_super_url, caplog, create_script_04): # The following is the creation script from the ancient 0.4 version; this # is deliberately picked so we run through all subsequent update scripts # testing they all apply cleanly ... albeit with an empty database which # won't test the harder bits with db.begin(): for statement in parse_statements(create_script_04): db.execute(statement) assert main(['--dsn', db_super_url, '--user', PIWHEELS_USER, '--yes']) == 0 with db.begin(): for row in db.execute("SELECT version FROM configuration"): assert row[0] == __version__ break else: assert False, "Didn't find version row in configuration" assert find_message(caplog.records, message='Upgrading database to ' 'version %s' % __version__)
def test_current_version(db, with_schema, db_super_url, caplog): with mock.patch('piwheels.terminal.yes_no_prompt') as prompt_mock: prompt_mock.return_value = False assert main(['--dsn', db_super_url, '--user', PIWHEELS_USER]) == 0 assert find_message(caplog.records, 'Database is the current version')
def test_new_abort(db, with_clean_db, db_super_url, caplog): with mock.patch('piwheels.terminal.yes_no_prompt') as prompt_mock: prompt_mock.return_value = False assert main(['--dsn', db_super_url, '--user', PIWHEELS_USER]) == 0 assert find_message(caplog.records, 'Database appears to be uninitialized')
def test_full_upgrade(db, with_clean_db, db_super_url, caplog): # The following is the creation script from the ancient 0.4 version; this # is deliberately picked so we run through all subsequent update scripts # testing they all apply cleanly create_04 = """ CREATE TABLE packages ( package VARCHAR(200) NOT NULL, skip BOOLEAN DEFAULT false NOT NULL, CONSTRAINT packages_pk PRIMARY KEY (package) ); GRANT SELECT,INSERT,UPDATE,DELETE ON packages TO piwheels; CREATE INDEX packages_skip ON packages(skip); CREATE TABLE versions ( package VARCHAR(200) NOT NULL, version VARCHAR(200) NOT NULL, skip BOOLEAN DEFAULT false NOT NULL, CONSTRAINT versions_pk PRIMARY KEY (package, version), CONSTRAINT versions_package_fk FOREIGN KEY (package) REFERENCES packages ON DELETE RESTRICT ); GRANT SELECT,INSERT,UPDATE,DELETE ON versions TO piwheels; CREATE INDEX versions_skip ON versions(skip); CREATE TABLE builds ( build_id SERIAL NOT NULL, package VARCHAR(200) NOT NULL, version VARCHAR(200) NOT NULL, built_by INTEGER NOT NULL, built_at TIMESTAMP NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'), duration INTERVAL NOT NULL, status BOOLEAN DEFAULT true NOT NULL, output TEXT NOT NULL, CONSTRAINT builds_pk PRIMARY KEY (build_id), CONSTRAINT builds_unique UNIQUE (package, version, built_at, built_by), CONSTRAINT builds_versions_fk FOREIGN KEY (package, version) REFERENCES versions ON DELETE CASCADE, CONSTRAINT builds_built_by_ck CHECK (built_by >= 1) ); GRANT SELECT,INSERT,UPDATE,DELETE ON builds TO piwheels; CREATE INDEX builds_timestamp ON builds(built_at DESC NULLS LAST); CREATE INDEX builds_pkgver ON builds(package, version); CREATE TABLE files ( filename VARCHAR(255) NOT NULL, build_id INTEGER NOT NULL, filesize INTEGER NOT NULL, filehash CHAR(64) NOT NULL, package_version_tag VARCHAR(100) NOT NULL, py_version_tag VARCHAR(100) NOT NULL, abi_tag VARCHAR(100) NOT NULL, platform_tag VARCHAR(100) NOT NULL, CONSTRAINT files_pk PRIMARY KEY (filename), CONSTRAINT files_builds_fk FOREIGN KEY (build_id) REFERENCES builds (build_id) ON DELETE CASCADE ); GRANT SELECT,INSERT,UPDATE,DELETE ON files TO piwheels; CREATE UNIQUE INDEX files_pkgver ON files(build_id); CREATE INDEX files_size ON files(filesize); """ with db.begin(): for statement in parse_statements(create_04): db.execute(statement) assert main(['--dsn', db_super_url, '--user', PIWHEELS_USER, '--yes']) == 0 with db.begin(): for row in db.execute("SELECT version FROM configuration"): assert row[0] == __version__ break else: assert False, "Didn't find version row in configuration" assert find_message(caplog.records, 'Upgrading database to version %s' % __version__)