OSPPCloudUniversity3/addons/queue_job/tests/test_delayable.py

272 lines
9.8 KiB
Python

# copyright 2019 Camptocamp
# license agpl-3.0 or later (http://www.gnu.org/licenses/agpl.html)
import unittest
from unittest import mock
from odoo.addons.queue_job.delay import Delayable, DelayableGraph
class TestDelayable(unittest.TestCase):
def setUp(self):
super().setUp()
self.recordset = mock.MagicMock(name="recordset")
def test_delayable_set(self):
dl = Delayable(self.recordset)
dl.set(priority=15)
self.assertEqual(dl.priority, 15)
dl.set({"priority": 20, "description": "test"})
self.assertEqual(dl.priority, 20)
self.assertEqual(dl.description, "test")
def test_delayable_set_unknown(self):
dl = Delayable(self.recordset)
with self.assertRaises(ValueError):
dl.set(foo=15)
def test_graph_add_vertex_edge(self):
graph = DelayableGraph()
graph.add_vertex("a")
self.assertEqual(graph._graph, {"a": set()})
graph.add_edge("a", "b")
self.assertEqual(graph._graph, {"a": {"b"}, "b": set()})
graph.add_edge("b", "c")
self.assertEqual(graph._graph, {"a": {"b"}, "b": {"c"}, "c": set()})
def test_graph_vertices(self):
graph = DelayableGraph({"a": {"b"}, "b": {"c"}, "c": set()})
self.assertEqual(graph.vertices(), {"a", "b", "c"})
def test_graph_edges(self):
graph = DelayableGraph(
{"a": {"b"}, "b": {"c", "d"}, "c": {"e"}, "d": set(), "e": set()}
)
self.assertEqual(
sorted(graph.edges()),
sorted(
[
("a", "b"),
("b", "c"),
("b", "d"),
("c", "e"),
]
),
)
def test_graph_connect(self):
node_tail = Delayable(self.recordset)
node_tail2 = Delayable(self.recordset)
node_middle = Delayable(self.recordset)
node_top = Delayable(self.recordset)
node_middle.on_done(node_tail)
node_middle.on_done(node_tail2)
node_top.on_done(node_middle)
collected = node_top._graph._connect_graphs()
self.assertEqual(
collected._graph,
{
node_tail: set(),
node_tail2: set(),
node_middle: {node_tail, node_tail2},
node_top: {node_middle},
},
)
def test_graph_paths(self):
graph = DelayableGraph(
{"a": {"b"}, "b": {"c", "d"}, "c": {"e"}, "d": set(), "e": set()}
)
paths = list(graph.paths("a"))
self.assertEqual(sorted(paths), sorted([["a", "b", "d"], ["a", "b", "c", "e"]]))
paths = list(graph.paths("b"))
self.assertEqual(sorted(paths), sorted([["b", "d"], ["b", "c", "e"]]))
paths = list(graph.paths("c"))
self.assertEqual(paths, [["c", "e"]])
paths = list(graph.paths("d"))
self.assertEqual(paths, [["d"]])
paths = list(graph.paths("e"))
self.assertEqual(paths, [["e"]])
def test_graph_repr(self):
graph = DelayableGraph(
{"a": {"b"}, "b": {"c", "d"}, "c": {"e"}, "d": set(), "e": set()}
)
actual = repr(graph)
expected = ["'a''b''c''e'", "'a''b''d'"]
self.assertEqual(sorted(actual.split("\n")), expected)
def test_graph_topological_sort(self):
# the graph is an example from
# https://en.wikipedia.org/wiki/Topological_sorting
# if you want a visual representation
graph = DelayableGraph(
{
5: {11},
7: {11, 8},
3: {8, 10},
11: {2, 9, 10},
2: set(),
8: {9},
9: set(),
10: set(),
}
)
# these are all the pre-computed combinations that
# respect the dependencies order
valid_solutions = [
[3, 5, 7, 8, 11, 2, 9, 10],
[3, 5, 7, 8, 11, 2, 10, 9],
[3, 5, 7, 8, 11, 9, 2, 10],
[3, 5, 7, 8, 11, 9, 10, 2],
[3, 5, 7, 8, 11, 10, 2, 9],
[3, 5, 7, 8, 11, 10, 9, 2],
[3, 5, 7, 11, 2, 8, 9, 10],
[3, 5, 7, 11, 2, 8, 10, 9],
[3, 5, 7, 11, 2, 10, 8, 9],
[3, 5, 7, 11, 8, 2, 9, 10],
[3, 5, 7, 11, 8, 2, 10, 9],
[3, 5, 7, 11, 8, 9, 2, 10],
[3, 5, 7, 11, 8, 9, 10, 2],
[3, 5, 7, 11, 8, 10, 2, 9],
[3, 5, 7, 11, 8, 10, 9, 2],
[3, 5, 7, 11, 10, 2, 8, 9],
[3, 5, 7, 11, 10, 8, 2, 9],
[3, 5, 7, 11, 10, 8, 9, 2],
[3, 7, 5, 8, 11, 2, 9, 10],
[3, 7, 5, 8, 11, 2, 10, 9],
[3, 7, 5, 8, 11, 9, 2, 10],
[3, 7, 5, 8, 11, 9, 10, 2],
[3, 7, 5, 8, 11, 10, 2, 9],
[3, 7, 5, 8, 11, 10, 9, 2],
[3, 7, 5, 11, 2, 8, 9, 10],
[3, 7, 5, 11, 2, 8, 10, 9],
[3, 7, 5, 11, 2, 10, 8, 9],
[3, 7, 5, 11, 8, 2, 9, 10],
[3, 7, 5, 11, 8, 2, 10, 9],
[3, 7, 5, 11, 8, 9, 2, 10],
[3, 7, 5, 11, 8, 9, 10, 2],
[3, 7, 5, 11, 8, 10, 2, 9],
[3, 7, 5, 11, 8, 10, 9, 2],
[3, 7, 5, 11, 10, 2, 8, 9],
[3, 7, 5, 11, 10, 8, 2, 9],
[3, 7, 5, 11, 10, 8, 9, 2],
[3, 7, 8, 5, 11, 2, 9, 10],
[3, 7, 8, 5, 11, 2, 10, 9],
[3, 7, 8, 5, 11, 9, 2, 10],
[3, 7, 8, 5, 11, 9, 10, 2],
[3, 7, 8, 5, 11, 10, 2, 9],
[3, 7, 8, 5, 11, 10, 9, 2],
[5, 3, 7, 8, 11, 2, 9, 10],
[5, 3, 7, 8, 11, 2, 10, 9],
[5, 3, 7, 8, 11, 9, 2, 10],
[5, 3, 7, 8, 11, 9, 10, 2],
[5, 3, 7, 8, 11, 10, 2, 9],
[5, 3, 7, 8, 11, 10, 9, 2],
[5, 3, 7, 11, 2, 8, 9, 10],
[5, 3, 7, 11, 2, 8, 10, 9],
[5, 3, 7, 11, 2, 10, 8, 9],
[5, 3, 7, 11, 8, 2, 9, 10],
[5, 3, 7, 11, 8, 2, 10, 9],
[5, 3, 7, 11, 8, 9, 2, 10],
[5, 3, 7, 11, 8, 9, 10, 2],
[5, 3, 7, 11, 8, 10, 2, 9],
[5, 3, 7, 11, 8, 10, 9, 2],
[5, 3, 7, 11, 10, 2, 8, 9],
[5, 3, 7, 11, 10, 8, 2, 9],
[5, 3, 7, 11, 10, 8, 9, 2],
[5, 7, 3, 8, 11, 2, 9, 10],
[5, 7, 3, 8, 11, 2, 10, 9],
[5, 7, 3, 8, 11, 9, 2, 10],
[5, 7, 3, 8, 11, 9, 10, 2],
[5, 7, 3, 8, 11, 10, 2, 9],
[5, 7, 3, 8, 11, 10, 9, 2],
[5, 7, 3, 11, 2, 8, 9, 10],
[5, 7, 3, 11, 2, 8, 10, 9],
[5, 7, 3, 11, 2, 10, 8, 9],
[5, 7, 3, 11, 8, 2, 9, 10],
[5, 7, 3, 11, 8, 2, 10, 9],
[5, 7, 3, 11, 8, 9, 2, 10],
[5, 7, 3, 11, 8, 9, 10, 2],
[5, 7, 3, 11, 8, 10, 2, 9],
[5, 7, 3, 11, 8, 10, 9, 2],
[5, 7, 3, 11, 10, 2, 8, 9],
[5, 7, 3, 11, 10, 8, 2, 9],
[5, 7, 3, 11, 10, 8, 9, 2],
[5, 7, 11, 2, 3, 8, 9, 10],
[5, 7, 11, 2, 3, 8, 10, 9],
[5, 7, 11, 2, 3, 10, 8, 9],
[5, 7, 11, 3, 2, 8, 9, 10],
[5, 7, 11, 3, 2, 8, 10, 9],
[5, 7, 11, 3, 2, 10, 8, 9],
[5, 7, 11, 3, 8, 2, 9, 10],
[5, 7, 11, 3, 8, 2, 10, 9],
[5, 7, 11, 3, 8, 9, 2, 10],
[5, 7, 11, 3, 8, 9, 10, 2],
[5, 7, 11, 3, 8, 10, 2, 9],
[5, 7, 11, 3, 8, 10, 9, 2],
[5, 7, 11, 3, 10, 2, 8, 9],
[5, 7, 11, 3, 10, 8, 2, 9],
[5, 7, 11, 3, 10, 8, 9, 2],
[7, 3, 5, 8, 11, 2, 9, 10],
[7, 3, 5, 8, 11, 2, 10, 9],
[7, 3, 5, 8, 11, 9, 2, 10],
[7, 3, 5, 8, 11, 9, 10, 2],
[7, 3, 5, 8, 11, 10, 2, 9],
[7, 3, 5, 8, 11, 10, 9, 2],
[7, 3, 5, 11, 2, 8, 9, 10],
[7, 3, 5, 11, 2, 8, 10, 9],
[7, 3, 5, 11, 2, 10, 8, 9],
[7, 3, 5, 11, 8, 2, 9, 10],
[7, 3, 5, 11, 8, 2, 10, 9],
[7, 3, 5, 11, 8, 9, 2, 10],
[7, 3, 5, 11, 8, 9, 10, 2],
[7, 3, 5, 11, 8, 10, 2, 9],
[7, 3, 5, 11, 8, 10, 9, 2],
[7, 3, 5, 11, 10, 2, 8, 9],
[7, 3, 5, 11, 10, 8, 2, 9],
[7, 3, 5, 11, 10, 8, 9, 2],
[7, 3, 8, 5, 11, 2, 9, 10],
[7, 3, 8, 5, 11, 2, 10, 9],
[7, 3, 8, 5, 11, 9, 2, 10],
[7, 3, 8, 5, 11, 9, 10, 2],
[7, 3, 8, 5, 11, 10, 2, 9],
[7, 3, 8, 5, 11, 10, 9, 2],
[7, 5, 3, 8, 11, 2, 9, 10],
[7, 5, 3, 8, 11, 2, 10, 9],
[7, 5, 3, 8, 11, 9, 2, 10],
[7, 5, 3, 8, 11, 9, 10, 2],
[7, 5, 3, 8, 11, 10, 2, 9],
[7, 5, 3, 8, 11, 10, 9, 2],
[7, 5, 3, 11, 2, 8, 9, 10],
[7, 5, 3, 11, 2, 8, 10, 9],
[7, 5, 3, 11, 2, 10, 8, 9],
[7, 5, 3, 11, 8, 2, 9, 10],
[7, 5, 3, 11, 8, 2, 10, 9],
[7, 5, 3, 11, 8, 9, 2, 10],
[7, 5, 3, 11, 8, 9, 10, 2],
[7, 5, 3, 11, 8, 10, 2, 9],
[7, 5, 3, 11, 8, 10, 9, 2],
[7, 5, 3, 11, 10, 2, 8, 9],
[7, 5, 3, 11, 10, 8, 2, 9],
[7, 5, 3, 11, 10, 8, 9, 2],
[7, 5, 11, 2, 3, 8, 9, 10],
[7, 5, 11, 2, 3, 8, 10, 9],
[7, 5, 11, 2, 3, 10, 8, 9],
[7, 5, 11, 3, 2, 8, 9, 10],
[7, 5, 11, 3, 2, 8, 10, 9],
[7, 5, 11, 3, 2, 10, 8, 9],
[7, 5, 11, 3, 8, 2, 9, 10],
[7, 5, 11, 3, 8, 2, 10, 9],
[7, 5, 11, 3, 8, 9, 2, 10],
[7, 5, 11, 3, 8, 9, 10, 2],
[7, 5, 11, 3, 8, 10, 2, 9],
[7, 5, 11, 3, 8, 10, 9, 2],
[7, 5, 11, 3, 10, 2, 8, 9],
[7, 5, 11, 3, 10, 8, 2, 9],
[7, 5, 11, 3, 10, 8, 9, 2],
]
self.assertIn(list(graph.topological_sort()), valid_solutions)