2021-08-20 07:12:50 +00:00
|
|
|
"""
|
|
|
|
Tests covering the jobq API
|
|
|
|
"""
|
|
|
|
|
|
|
|
import logging
|
|
|
|
from time import sleep
|
|
|
|
|
|
|
|
from jobq import Job, JobQueue
|
|
|
|
import pytest
|
|
|
|
|
2021-08-30 04:18:57 +00:00
|
|
|
|
2021-08-20 07:12:50 +00:00
|
|
|
logging.getLogger().setLevel(logging.DEBUG)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def db():
|
|
|
|
return JobQueue(":memory:")
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def payload():
|
|
|
|
return "a basic payload"
|
|
|
|
|
|
|
|
|
|
|
|
def test_create(db, payload):
|
|
|
|
"""Assert that create does the thing."""
|
|
|
|
|
|
|
|
j = db.create(payload)
|
|
|
|
|
|
|
|
assert j
|
|
|
|
assert isinstance(j, Job)
|
|
|
|
assert j.id == 1
|
|
|
|
assert j.payload == payload
|
|
|
|
|
|
|
|
|
|
|
|
def test_create_get(db, payload):
|
|
|
|
"""Assert that get-after-create returns the same value."""
|
|
|
|
|
|
|
|
j = db.create(payload)
|
|
|
|
|
|
|
|
assert j == db.get(j.id)
|
|
|
|
|
|
|
|
|
|
|
|
def test_poll(db):
|
|
|
|
"""Test that we can poll a job, and the oldest wins."""
|
|
|
|
|
|
|
|
j1 = db.create("payload 1")
|
|
|
|
j2 = db.create("payload 2")
|
|
|
|
assert j1.modified == j2.modified, "Two within the second to force the `rowid` ASC"
|
2021-08-30 07:06:21 +00:00
|
|
|
sleep(1) # And a side-effect for the third one
|
|
|
|
db.create("payload 3")
|
2021-08-20 07:12:50 +00:00
|
|
|
|
2021-08-30 04:18:57 +00:00
|
|
|
j = db.poll("true", ["assigned"])
|
2021-08-20 07:12:50 +00:00
|
|
|
|
|
|
|
assert isinstance(j, Job)
|
|
|
|
assert j.id == j1.id, "j1 is the oldest in the system and should poll first."
|
|
|
|
assert j.state == ["assigned"]
|
|
|
|
|
|
|
|
|
|
|
|
def test_poll_not_found(db):
|
|
|
|
"""Test that poll can return nothing."""
|
|
|
|
|
2021-08-30 07:06:21 +00:00
|
|
|
db.create("payload 1")
|
2021-08-30 04:18:57 +00:00
|
|
|
j = db.poll("false", ["assigned"])
|
2021-08-20 07:12:50 +00:00
|
|
|
assert j is None
|
|
|
|
|
|
|
|
|
|
|
|
def test_append(db, payload):
|
|
|
|
"""Test that appending an event to the log does append and preserves invariants."""
|
|
|
|
|
|
|
|
j = db.create(payload)
|
2021-08-30 07:06:21 +00:00
|
|
|
sleep(1) # side-effect so that sqlite3 gets a different commit timestamp
|
2021-08-20 07:12:50 +00:00
|
|
|
j_prime = db.append_event(j.id, "some user-defined event")
|
|
|
|
|
|
|
|
assert isinstance(j_prime, Job)
|
|
|
|
assert j != j_prime
|
|
|
|
assert j_prime.id == j.id
|
|
|
|
assert j_prime.state == j.state
|
|
|
|
assert j_prime.modified > j.modified
|
|
|
|
assert j_prime.events != j.events
|
|
|
|
assert j_prime.events[:-1] == j.events
|
|
|
|
|
|
|
|
|
|
|
|
def test_cas_ok(db):
|
|
|
|
"""Test that we can CAS a job from one state to the 'next'."""
|
|
|
|
|
|
|
|
j = db.create("job2", ["state", 2])
|
2021-08-30 07:06:21 +00:00
|
|
|
sleep(1) # side-effect so that sqlite3 gets a different commit timestamp
|
2021-08-20 07:12:50 +00:00
|
|
|
j_prime = db.cas_state(j.id, ["state", 2], ["state", 3])
|
|
|
|
|
|
|
|
assert isinstance(j_prime, Job), "\n".join(db._db.iterdump())
|
|
|
|
assert j != j_prime
|
|
|
|
assert j_prime.id == j.id
|
|
|
|
assert j_prime.state != j.state
|
|
|
|
assert j_prime.modified > j.modified
|
|
|
|
assert j_prime.events != j.events
|
|
|
|
assert j_prime.events[:-1] == j.events
|
|
|
|
|
|
|
|
|
|
|
|
def test_cas_fail(db):
|
|
|
|
"""Test that if we have a 'stale' old state CAS fails."""
|
|
|
|
|
|
|
|
j = db.create("job2", ["state", 2])
|
|
|
|
j_prime = db.cas_state(j.id, ["state", 1], ["state", 2])
|
|
|
|
|
|
|
|
assert j_prime is None
|