# Copyright (C) 2018 Lars Wirzenius # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . import unittest import ick2 class BuildGraphTests(unittest.TestCase): def test_has_no_actions_initially(self): graph = ick2.BuildGraph() self.assertEqual(graph.get_actions(), {}) def test_initialises_from_existing_graph(self): as_dict = { '1': { 'action': {'action': 'foo'}, 'status': 'ready', 'depends': [], }, '2': { 'action': {'action': 'bar'}, 'status': ick2.ACTION_BLOCKED, 'depends': ['1'], }, } graph = ick2.BuildGraph(graph=as_dict) self.assertEqual(graph.get_actions(), as_dict) def test_appends_first_action(self): action = { 'action': 'foo', } graph = ick2.BuildGraph() action_id = graph.append_action(action) self.assertEqual(action_id, '1') self.assertEqual( graph.get_actions(), { action_id: { 'action': {'action': 'foo'}, 'status': ick2.ACTION_READY, 'depends': [] } } ) self.assertEqual(graph.get_action(action_id), action) def test_appends_second_action(self): action1 = { 'action': 'foo', } action2 = { 'action': 'bar', } graph = ick2.BuildGraph() action_id1 = graph.append_action(action1) action_id2 = graph.append_action(action2) self.assertEqual(action_id1, '1') self.assertEqual(action_id2, '2') self.assertEqual( graph.get_actions(), { action_id1: { 'action': {'action': 'foo'}, 'status': ick2.ACTION_READY, 'depends': [], }, action_id2: { 'action': {'action': 'bar'}, 'status': ick2.ACTION_BLOCKED, 'depends': [action_id1], }, } ) def test_changes_action_status(self): action = { 'action': 'foo', } graph = ick2.BuildGraph() action_id = graph.append_action(action) self.assertEqual(graph.get_action_status(action_id), ick2.ACTION_READY) graph.set_action_status(action_id, ick2.ACTION_BUILDING) self.assertEqual( graph.get_action_status(action_id), ick2.ACTION_BUILDING) def test_appends_pipeline_actions(self): pipeline_as_dict = { 'actions': [ { 'action': 'foo', }, { 'action': 'bar', }, ], } pipeline = ick2.resource_from_dict(pipeline_as_dict) graph = ick2.BuildGraph() graph.append_pipeline(pipeline) self.assertEqual( graph.get_actions(), { '1': { 'action': {'action': 'foo'}, 'depends': [], 'status': ick2.ACTION_READY, }, '2': { 'action': {'action': 'bar'}, 'depends': ['1'], 'status': ick2.ACTION_BLOCKED, }, } ) def test_appending_action_triggers_observer(self): def observer(): setattr(self, 'observed', True) action = {} setattr(self, 'observed', False) graph = ick2.BuildGraph() graph.set_observer(observer) self.assertFalse(getattr(self, 'observed')) action_id = graph.append_action(action) self.assertTrue(getattr(self, 'observed')) def test_finds_actions(self): pipeline_as_dict = { 'actions': [ { 'action': 'foo', }, { 'action': 'bar', }, ], } pipeline = ick2.resource_from_dict(pipeline_as_dict) graph = ick2.BuildGraph() graph.append_pipeline(pipeline) self.assertEqual(graph.find_actions('no-such-state'), []) self.assertEqual(graph.find_actions(ick2.ACTION_READY), ['1']) self.assertEqual(graph.find_actions(ick2.ACTION_BLOCKED), ['2']) def test_tracks_nothing_to_do(self): pipeline_as_dict = { 'actions': [ { 'action': 'foo', }, { 'action': 'bar', }, ], } pipeline = ick2.resource_from_dict(pipeline_as_dict) graph = ick2.BuildGraph() graph.append_pipeline(pipeline) def test_doesnt_unblock_when_deps_are_not_done(self): pipeline_as_dict = { 'actions': [ { 'action': 'foo', }, { 'action': 'bar', }, ], } pipeline = ick2.resource_from_dict(pipeline_as_dict) graph = ick2.BuildGraph() self.assertFalse(graph.has_more_to_do()) graph.append_pipeline(pipeline) graph.set_action_status('1', ick2.ACTION_BUILDING) self.assertEqual(graph.get_action_status('2'), ick2.ACTION_BLOCKED) self.assertTrue(graph.has_more_to_do()) graph.set_action_status('1', ick2.ACTION_DONE) self.assertEqual(graph.get_action_status('2'), ick2.ACTION_BLOCKED) self.assertFalse(graph.has_more_to_do()) graph.set_action_status('2', ick2.ACTION_READY) self.assertTrue(graph.has_more_to_do()) graph.set_action_status('2', ick2.ACTION_DONE) self.assertFalse(graph.has_more_to_do()) def test_unblocks_when_deps_are_done(self): pipeline_as_dict = { 'actions': [ { 'action': 'foo', }, { 'action': 'bar', }, ], } pipeline = ick2.resource_from_dict(pipeline_as_dict) graph = ick2.BuildGraph() graph.append_pipeline(pipeline) graph.set_action_status('1', ick2.ACTION_DONE) graph.unblock() self.assertEqual(graph.get_action_status('1'), ick2.ACTION_DONE) self.assertEqual(graph.get_action_status('2'), ick2.ACTION_READY)