pytest: test the db hook plugin.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2019-03-18 13:10:32 +10:30
parent 4ca2964d21
commit 7ccf3af51d
5 changed files with 76 additions and 7 deletions

39
tests/plugins/dblog.py Executable file
View File

@ -0,0 +1,39 @@
#!/usr/bin/env python3
"""This plugin is used to check that db_write calls are working correctly.
"""
from lightning import Plugin, RpcError
import sqlite3
plugin = Plugin()
plugin.sqlite_pre_init_cmds = []
plugin.initted = False
@plugin.init()
def init(configuration, options, plugin):
if not plugin.get_option('dblog-file'):
raise RpcError("No dblog-file specified")
plugin.conn = sqlite3.connect(plugin.get_option('dblog-file'),
isolation_level=None)
plugin.log("replaying pre-init data:")
for c in plugin.sqlite_pre_init_cmds:
plugin.conn.execute(c)
plugin.log("{}".format(c))
plugin.initted = True
plugin.log("initialized")
@plugin.hook('db_write')
def db_write(plugin, writes):
if not plugin.initted:
plugin.log("deferring {} commands".format(len(writes)))
plugin.sqlite_pre_init_cmds += writes
else:
for c in writes:
plugin.conn.execute(c)
plugin.log("{}".format(c))
return True
plugin.add_option('dblog-file', None, 'The db file to create.')
plugin.run()

View File

@ -3,7 +3,9 @@ from fixtures import * # noqa: F401,F403
from lightning import RpcError, Millisatoshi
from utils import only_one
import os
import pytest
import sqlite3
import subprocess
import time
@ -190,6 +192,31 @@ def test_async_rpcmethod(node_factory, executor):
assert [r.result() for r in results] == [42] * len(results)
def test_db_hook(node_factory, executor):
"""This tests the db hook."""
dbfile = os.path.join(node_factory.directory, "dblog.sqlite3")
l1 = node_factory.get_node(options={'plugin': 'tests/plugins/dblog.py',
'dblog-file': dbfile})
# It should see the db being created, and sometime later actually get
# initted.
# This precedes startup, so needle already past
assert l1.daemon.is_in_log('plugin-dblog.py deferring 1 commands')
l1.daemon.logsearch_start = 0
l1.daemon.wait_for_log('plugin-dblog.py replaying pre-init data:')
l1.daemon.wait_for_log('plugin-dblog.py PRAGMA foreign_keys = ON;')
l1.daemon.wait_for_log('plugin-dblog.py CREATE TABLE version \\(version INTEGER\\)')
l1.daemon.wait_for_log('plugin-dblog.py initialized')
l1.stop()
# Databases should be identical.
db1 = sqlite3.connect(os.path.join(l1.daemon.lightning_dir, 'lightningd.sqlite3'))
db2 = sqlite3.connect(dbfile)
assert [x for x in db1.iterdump()] == [x for x in db2.iterdump()]
def test_utf8_passthrough(node_factory, executor):
l1 = node_factory.get_node(options={'plugin': 'tests/plugins/utf8.py',
'log-level': 'io'})

View File

@ -7,6 +7,7 @@
#include <inttypes.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/plugin_hook.h>
#define DB_FILE "lightningd.sqlite3"
@ -578,13 +579,8 @@ static void db_report_changes(struct db *db, const char *final, size_t min)
assert(db->changes);
assert(tal_count(db->changes) >= min);
if (tal_count(db->changes) > min) {
fprintf(stderr, "Committing db changes:\n");
for (size_t i = 0; i < tal_count(db->changes); i++)
fprintf(stderr, " %zu: %s\n", i, db->changes[i]);
if (final)
fprintf(stderr, " %s\n", final);
}
if (tal_count(db->changes) > min)
plugin_hook_db_sync(db, db->changes, final);
db->changes = tal_free(db->changes);
}

View File

@ -37,6 +37,10 @@ static void db_test_fatal(const char *fmt, ...)
va_end(ap);
}
void plugin_hook_db_sync(struct db *db UNNEEDED, const char **changes UNNEEDED, const char *final UNNEEDED)
{
}
static struct db *create_test_db(void)
{
struct db *db;

View File

@ -564,6 +564,9 @@ u8 *wire_sync_read(const tal_t *ctx UNNEEDED, int fd UNNEEDED)
{
return NULL;
}
void plugin_hook_db_sync(struct db *db UNNEEDED, const char **changes UNNEEDED, const char *final UNNEEDED)
{
}
bool fromwire_hsm_get_channel_basepoints_reply(const void *p UNNEEDED,
struct basepoints *basepoints,
struct pubkey *funding_pubkey)