xfstestsdb: Create the `xfstestsdb new` command

This command inserts a new row into the xfstests_runs table and prints
out the result.

Note that sqlite stores timestamps as UTC, so I use the datetime()
function to convert to localtime when returning the new row.

Implements: #1 (`xfstestsdb new`)
Signed-off-by: Anna Schumaker <anna@nowheycreamery.com>
This commit is contained in:
Anna Schumaker 2023-02-01 10:13:42 -05:00
parent 2a94b5e519
commit 6a6fe5dda8
4 changed files with 82 additions and 1 deletions

38
tests/test_new.py Normal file
View File

@ -0,0 +1,38 @@
# Copyright 2023 (c) Anna Schumaker.
"""Tests the `xfstestsdb new` command."""
import io
import unittest
import unittest.mock
import xfstestsdb.new
class TestNew(unittest.TestCase):
"""Tests the `xfstestsdb new` command."""
def setUp(self):
"""Set up common variables."""
self.xfstestsdb = xfstestsdb.Command()
self.new = self.xfstestsdb.commands["new"]
def test_init(self):
"""Check that the new command was set up properly."""
self.assertIsInstance(self.new, xfstestsdb.commands.Command)
self.assertIsInstance(self.new, xfstestsdb.new.Command)
self.assertEqual(self.xfstestsdb.subparser.choices["new"],
self.new.parser)
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
def test_new(self, mock_stdout: io.StringIO):
"""Test running the `xfstestsdb new` command with correct input."""
self.xfstestsdb.run(["new", "/dev/vdb1"])
self.assertRegex(mock_stdout.getvalue(),
r"created run #1 with test device '/dev/vdb1' "
r"\[[\d\-\: ]+\]\n")
@unittest.mock.patch("sys.stderr", new_callable=io.StringIO)
def test_new_error(self, mock_stderr: io.StringIO):
"""Test running the `xfstestsdb new` command with invalid input."""
with self.assertRaises(SystemExit):
self.xfstestsdb.run(["new"])
self.assertRegex(mock_stderr.getvalue(),
"error: the following arguments are required: device")

View File

@ -2,6 +2,7 @@
"""Implements the toplevel xfstestsdb command."""
import argparse
from . import sqlite
from . import new
MAJOR = 1
MINOR = 0
@ -18,7 +19,7 @@ class Command:
help="show version number and exit")
self.subparser = self.parser.add_subparsers(title="commands")
self.sql = sqlite.Connection()
self.commands = {}
self.commands = {"new": new.Command(self.subparser, self.sql)}
def __del__(self) -> None:
"""Clean up."""

29
xfstestsdb/new.py Normal file
View File

@ -0,0 +1,29 @@
# Copyright 2023 (c) Anna Schumaker.
"""The `xfstestsdb new` command."""
import argparse
from . import commands
from . import sqlite
class Command(commands.Command):
"""The `xfstestsdb new` command."""
def __init__(self, subparser: argparse.Action,
sql: sqlite.Connection) -> None:
"""Set up the New command."""
super().__init__(subparser, sql, "new",
help="create a new xfstests run")
self.parser.add_argument("device", metavar="device", nargs=1,
help="the test device used for"
"this xfstests run")
def do_command(self, args: argparse.Namespace) -> None:
"""Create a new row in the xfstestsdb_runs table."""
cur = self.sql("""INSERT INTO xfstests_runs (device)
VALUES (?) RETURNING rowid, device,
datetime(timestamp, 'localtime') as timestamp""",
args.device[0])
row = cur.fetchone()
print(f"created run #{row['runid']}", end=" ")
print(f"with test device '{row['device']}'", end=" ")
print(f"[{row['timestamp']}]")

View File

@ -2,3 +2,16 @@
PRAGMA foreign_keys = ON;
PRAGMA user_version = 1;
/************************************************************
* *
* Table for storing individual xfstests runs *
* *
************************************************************/
CREATE TABLE xfstests_runs (
runid INTEGER PRIMARY KEY,
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
device TEXT NOT NULL
);