import omni.graph.core as og
import omni.graph.core.tests as ogts
import omni.kit.commands
import omni.kit.test
import omni.usd
from pxr import Gf, UsdGeom


class TestImportNodes(ogts.OmniGraphTestCase):

    TEST_GRAPH_PATH = "/World/TestGraph"

    async def test_import_time_samples(self):
        await self._test_import_time_samples_impl("omni.graph.nodes.ReadPrimsV2")

    async def test_import_time_samples_legacy(self):
        await self._test_import_time_samples_impl("omni.graph.nodes.ReadPrims")

    async def _test_import_time_samples_impl(self, read_prims_node_type: str):
        """Verify that time sample data is correctly imported"""
        (result, error) = await ogts.load_test_file("TestUSDTimeCode.usda", use_caller_subdirectory=True)
        self.assertTrue(result, f"{error}")

        controller = og.Controller()
        keys = og.Controller.Keys

        (_, nodes, cube, _) = controller.edit(
            "/TestGraph",
            {
                keys.CREATE_NODES: [
                    ("ReadPrimsBundle", "omni.graph.nodes.ReadPrimsBundle"),
                    ("ReadAttr", "omni.graph.nodes.ReadPrimAttribute"),
                    ("ExtractRPB", "omni.graph.nodes.ExtractBundle"),
                    ("ExtractRP", "omni.graph.nodes.ExtractBundle"),
                    ("ExtractPrimRPB", "omni.graph.nodes.ExtractPrim"),
                    ("ExtractPrimRP", "omni.graph.nodes.ExtractPrim"),
                    ("ReadPrims", read_prims_node_type),
                    ("Const", "omni.graph.nodes.ConstantDouble"),
                    ("Const2", "omni.graph.nodes.ConstantDouble"),
                ],
                keys.CREATE_PRIMS: [
                    ("/World/Cube2", "Cube"),
                ],
                keys.SET_VALUES: [
                    ("ReadAttr.inputs:usePath", True),
                    ("ReadAttr.inputs:primPath", "/World/Cube"),
                    ("ExtractPrimRPB.inputs:primPath", "/World/Cube"),
                    ("ExtractPrimRP.inputs:primPath", "/World/Cube"),
                    ("ReadAttr.inputs:name", "size"),
                    ("ReadAttr.inputs:usdTimecode", 0),
                    ("ReadPrimsBundle.inputs:usdTimecode", 0),
                    ("ReadPrims.inputs:usdTimecode", 0),
                ],
                keys.CONNECT: [
                    ("ReadPrimsBundle.outputs_primsBundle", "ExtractPrimRPB.inputs:prims"),
                    ("ExtractPrimRPB.outputs_primBundle", "ExtractRPB.inputs:bundle"),
                    ("ReadPrims.outputs_primsBundle", "ExtractPrimRP.inputs:prims"),
                    ("ExtractPrimRP.outputs_primBundle", "ExtractRP.inputs:bundle"),
                ],
            },
        )

        stage = omni.usd.get_context().get_stage()

        input_prim_prop = stage.GetPropertyAtPath("/TestGraph/ReadPrimsBundle.inputs:prims")
        omni.kit.commands.execute("AddRelationshipTarget", relationship=input_prim_prop, target="/World/Cube")

        input_prim_prop = stage.GetPropertyAtPath("/TestGraph/ReadPrims.inputs:prims")
        omni.kit.commands.execute("AddRelationshipTarget", relationship=input_prim_prop, target="/World/Cube")

        # evaluate so dynamic attributes are created
        await controller.evaluate()

        # connect the size attribute so it gets updated
        controller.edit(
            "/TestGraph",
            {
                keys.CONNECT: [
                    ("ExtractRPB.outputs:size", "Const.inputs:value"),
                    ("ExtractRP.outputs:size", "Const2.inputs:value"),
                ]
            },
        )

        cs = 10
        cube_size = cube[0].GetProperty("size")
        cube_size.Set(cs)

        await controller.evaluate()

        out_from_read_attr = nodes[1].get_attribute("outputs:value")
        out_from_read_prims_bundle = nodes[2].get_attribute("outputs:size")
        out_from_read_prims = nodes[3].get_attribute("outputs:size")

        self.assertTrue(out_from_read_attr.get() == 100)
        self.assertTrue(out_from_read_prims_bundle.get() == 100)
        self.assertTrue(out_from_read_prims.get() == 100)

        controller.edit(
            "/TestGraph",
            {
                keys.SET_VALUES: [
                    ("ReadAttr.inputs:usdTimecode", 25),
                    ("ReadPrimsBundle.inputs:usdTimecode", 25),
                    ("ReadPrims.inputs:usdTimecode", 25),
                ]
            },
        )
        await controller.evaluate()

        self.assertTrue(out_from_read_attr.get() == 50)
        self.assertTrue(out_from_read_prims_bundle.get() == 50)
        self.assertTrue(out_from_read_prims.get() == 50)

        controller.edit(
            "/TestGraph",
            {
                keys.SET_VALUES: [
                    ("ReadAttr.inputs:usdTimecode", 50),
                    ("ReadPrimsBundle.inputs:usdTimecode", 50),
                    ("ReadPrims.inputs:usdTimecode", 50),
                ]
            },
        )
        await controller.evaluate()

        self.assertTrue(out_from_read_attr.get() == 1)
        self.assertTrue(out_from_read_prims_bundle.get() == 1)
        self.assertTrue(out_from_read_prims.get() == 1)

        # now check that if we change the targets, the values correctly update
        controller.edit(
            "/TestGraph",
            {
                keys.SET_VALUES: [
                    ("ReadAttr.inputs:primPath", "/World/Cube2"),
                    ("ExtractPrimRPB.inputs:primPath", "/World/Cube2"),
                    ("ExtractPrimRP.inputs:primPath", "/World/Cube2"),
                ]
            },
        )

        input_prim_prop = stage.GetPropertyAtPath("/TestGraph/ReadPrimsBundle.inputs:prims")
        omni.kit.commands.execute("AddRelationshipTarget", relationship=input_prim_prop, target="/World/Cube2")

        input_prim_prop = stage.GetPropertyAtPath("/TestGraph/ReadPrims.inputs:prims")
        omni.kit.commands.execute("AddRelationshipTarget", relationship=input_prim_prop, target="/World/Cube2")

        await controller.evaluate()

        self.assertTrue(out_from_read_attr.get() == cs)
        self.assertTrue(out_from_read_prims_bundle.get() == cs)
        self.assertTrue(out_from_read_prims.get() == cs)

    async def test_import_matrix_and_bbox(self):
        await self._test_import_matrix_and_bbox_impl("omni.graph.nodes.ReadPrimsV2")

    async def test_import_matrix_and_bbox_legacy(self):
        await self._test_import_matrix_and_bbox_impl("omni.graph.nodes.ReadPrims")

    async def _test_import_matrix_and_bbox_impl(self, read_prims_node_type: str):
        # Verify that bounding box and matrix are correctly computed
        controller = og.Controller()
        keys = og.Controller.Keys
        usd_context = omni.usd.get_context()
        stage = usd_context.get_stage()
        cube = ogts.create_cube(stage, "World/Cube", (1, 1, 1))
        UsdGeom.Xformable(cube).AddTranslateOp()

        (_, nodes, _, _) = controller.edit(
            "/TestGraph",
            {
                keys.CREATE_NODES: [
                    ("ReadPrims", read_prims_node_type),
                    ("ExtractPrim", "omni.graph.nodes.ExtractPrim"),
                    ("ExtractBundle", "omni.graph.nodes.ExtractBundle"),
                    ("Inv", "omni.graph.nodes.OgnInvertMatrix"),
                    ("Const0", "omni.graph.nodes.ConstantDouble3"),
                    ("Const1", "omni.graph.nodes.ConstantDouble3"),
                ],
                keys.SET_VALUES: [
                    ("ReadPrims.inputs:pathPattern", "/World/Cube"),
                    ("ExtractPrim.inputs:primPath", "/World/Cube"),
                ],
                keys.CONNECT: [
                    ("ReadPrims.outputs_primsBundle", "ExtractPrim.inputs:prims"),
                    ("ExtractPrim.outputs_primBundle", "ExtractBundle.inputs:bundle"),
                ],
            },
        )

        if read_prims_node_type == "omni.graph.nodes.ReadPrims":
            controller.edit("/TestGraph", {keys.SET_VALUES: [("ReadPrims.inputs:useFindPrims", True)]})

        extract_bundle = nodes[2]

        # creates dynamic attributes
        await controller.evaluate()

        # connect the matrix
        controller.edit("/TestGraph", {keys.CONNECT: ("ExtractBundle.outputs:worldMatrix", "Inv.inputs:matrix")})

        # get initial output
        await controller.evaluate()

        # We did not ask for BBox
        self.assertFalse(extract_bundle.get_attribute_exists("outputs:bboxMinCorner"))
        self.assertFalse(extract_bundle.get_attribute_exists("outputs:bboxMaxCorner"))
        self.assertFalse(extract_bundle.get_attribute_exists("outputs:bboxTransform"))

        # but we should have the default matrix
        mat_attr = extract_bundle.get_attribute("outputs:worldMatrix")
        mat = mat_attr.get()
        self.assertTrue((mat == [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]).all())

        # move the cube, check the new matrix
        pos = cube.GetAttribute("xformOp:translate")
        pos.Set((2, 2, 2))

        await controller.evaluate()

        mat = mat_attr.get()
        self.assertTrue((mat == [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 2, 2, 1]).all())

        # now ask for bbox, and check its value
        controller.edit(
            "/TestGraph",
            {
                keys.SET_VALUES: ("ReadPrims.inputs:computeBoundingBox", True),
            },
        )
        await controller.evaluate()
        self.assertTrue(extract_bundle.get_attribute_exists("outputs:bboxMinCorner"))
        self.assertTrue(extract_bundle.get_attribute_exists("outputs:bboxMaxCorner"))
        self.assertTrue(extract_bundle.get_attribute_exists("outputs:bboxTransform"))

        # connect the bbox
        controller.edit(
            "/TestGraph",
            {
                keys.CONNECT: [
                    ("ExtractBundle.outputs:bboxMinCorner", "Const0.inputs:value"),
                    ("ExtractBundle.outputs:bboxMaxCorner", "Const1.inputs:value"),
                ]
            },
        )

        await controller.evaluate()

        bbox_min = extract_bundle.get_attribute("outputs:bboxMinCorner")
        bbox_max = extract_bundle.get_attribute("outputs:bboxMaxCorner")

        bbox_min_val = bbox_min.get()
        bbox_max_val = bbox_max.get()

        self.assertTrue((bbox_min_val == [-0.5, -0.5, -0.5]).all())
        self.assertTrue((bbox_max_val == [0.5, 0.5, 0.5]).all())

        # then resize the cube, and check new bbox
        ext = cube.GetAttribute("extent")
        ext.Set([(-10, -10, -10), (10, 10, 10)])

        await controller.evaluate()

        bbox_min_val = bbox_min.get()
        bbox_max_val = bbox_max.get()

        self.assertTrue((bbox_min_val == [-10, -10, -10]).all())
        self.assertTrue((bbox_max_val == [10, 10, 10]).all())

    async def test_readomnigraphvalue_tuple(self):
        """Test ReadOmniGraphValue by reading from a constant node (tuple)"""

        test_value = Gf.Vec3d(1.0, 2.0, 3.0)

        controller = og.Controller()
        keys = og.Controller.Keys

        (graph, (var_node, get_node), _, _) = controller.edit(
            self.TEST_GRAPH_PATH,
            {
                keys.CREATE_NODES: [
                    ("Var", "omni.graph.nodes.ConstantDouble3"),
                    ("Get", "omni.graph.nodes.ReadOmniGraphValue"),
                ],
                keys.SET_VALUES: [
                    ("Var.inputs:value", test_value),
                    ("Get.inputs:path", f"{self.TEST_GRAPH_PATH}/Var"),
                    ("Get.inputs:name", "inputs:value"),
                ],
            },
        )
        await controller.evaluate(graph)

        out_controller = og.Controller(og.Controller.attribute("outputs:value", get_node))
        v = out_controller.get()
        self.assertEqual(v[0], test_value[0])
        self.assertEqual(v[1], test_value[1])
        self.assertEqual(v[2], test_value[2])

        # try editing value
        test_value = Gf.Vec3d(4.0, 5.0, 6.0)
        og.Controller.attribute("inputs:value", var_node).set(test_value)
        await controller.evaluate(graph)
        v = out_controller.get()
        self.assertEqual(v[0], test_value[0])
        self.assertEqual(v[1], test_value[1])
        self.assertEqual(v[2], test_value[2])

    async def test_readomnigraphvalue_single(self):
        """Test ReadOmniGraphValue by reading from a constant node (single)"""

        test_value = 1337

        controller = og.Controller()
        keys = og.Controller.Keys

        (graph, (var_node, get_node), _, _) = controller.edit(
            self.TEST_GRAPH_PATH,
            {
                keys.CREATE_NODES: [
                    ("Var", "omni.graph.nodes.ConstantInt"),
                    ("Get", "omni.graph.nodes.ReadOmniGraphValue"),
                ],
                keys.SET_VALUES: [
                    ("Var.inputs:value", test_value),
                    ("Get.inputs:path", f"{self.TEST_GRAPH_PATH}/Var"),
                    ("Get.inputs:name", "inputs:value"),
                ],
            },
        )
        await controller.evaluate(graph)

        out_controller = og.Controller(og.Controller.attribute("outputs:value", get_node))
        v = out_controller.get()
        self.assertEqual(v, test_value)

        # try editing value
        test_value = 42
        og.Controller.attribute("inputs:value", var_node).set(test_value)
        await controller.evaluate(graph)
        v = out_controller.get()
        self.assertEqual(v, test_value)

    async def test_readomnigraphvalue_string(self):
        """Test ReadOmniGraphValue by reading from a constant node (string)"""

        test_value = "test value"

        controller = og.Controller()
        keys = og.Controller.Keys

        (graph, (var_node, get_node), _, _) = controller.edit(
            self.TEST_GRAPH_PATH,
            {
                keys.CREATE_NODES: [
                    ("Var", "omni.graph.nodes.ConstantString"),
                    ("Get", "omni.graph.nodes.ReadOmniGraphValue"),
                ],
                keys.SET_VALUES: [
                    ("Var.inputs:value", test_value),
                    ("Get.inputs:path", f"{self.TEST_GRAPH_PATH}/Var"),
                    ("Get.inputs:name", "inputs:value"),
                ],
            },
        )
        await controller.evaluate(graph)

        out_controller = og.Controller(og.Controller.attribute("outputs:value", get_node))
        v = out_controller.get()
        self.assertEqual(v, test_value)

        # try editing value
        test_value = "test value 2"
        og.Controller.attribute("inputs:value", var_node).set(test_value)
        await controller.evaluate(graph)
        v = out_controller.get()
        self.assertEqual(v, test_value)

    async def test_readomnigraphvalue_array(self):
        """Test ReadOmniGraphValue by reading from a constant node (array)"""

        test_values = [1.0, 2.0, 3.0]

        controller = og.Controller()
        keys = og.Controller.Keys

        (graph, (val0, val1, val2, _, get_node), _, _) = controller.edit(
            self.TEST_GRAPH_PATH,
            {
                keys.CREATE_NODES: [
                    ("Val0", "omni.graph.nodes.ConstantHalf"),
                    ("Val1", "omni.graph.nodes.ConstantHalf"),
                    ("Val2", "omni.graph.nodes.ConstantHalf"),
                    ("Array", "omni.graph.nodes.MakeArray"),
                    ("Get", "omni.graph.nodes.ReadOmniGraphValue"),
                ],
                keys.CONNECT: [
                    ("Val0.inputs:value", "Array.inputs:a"),
                    ("Val1.inputs:value", "Array.inputs:b"),
                    ("Val2.inputs:value", "Array.inputs:c"),
                ],
                keys.SET_VALUES: [
                    ("Array.inputs:arraySize", 3),
                    ("Val0.inputs:value", test_values[0]),
                    ("Val1.inputs:value", test_values[1]),
                    ("Val2.inputs:value", test_values[2]),
                    ("Get.inputs:path", f"{self.TEST_GRAPH_PATH}/Array"),
                    ("Get.inputs:name", "outputs:array"),
                ],
            },
        )
        await controller.evaluate(graph)

        out_controller = og.Controller(og.Controller.attribute("outputs:value", get_node))
        v = out_controller.get()
        self.assertEqual(v[0], test_values[0])
        self.assertEqual(v[1], test_values[1])
        self.assertEqual(v[2], test_values[2])

        # # try editing value
        test_values = [4.0, 5.0, 6.0]
        og.Controller.attribute("inputs:value", val0).set(test_values[0])
        og.Controller.attribute("inputs:value", val1).set(test_values[1])
        og.Controller.attribute("inputs:value", val2).set(test_values[2])
        await controller.evaluate(graph)
        v = out_controller.get()
        self.assertEqual(v[0], test_values[0])
        self.assertEqual(v[1], test_values[1])
        self.assertEqual(v[2], test_values[2])

    async def test_readomnigraphvalue_tuple_array(self):
        """Test ReadOmniGraphValue by reading from a constant node (array of tuple)"""

        test_values = [Gf.Vec4f(1.0, 2.0, 3.0, 4.0), Gf.Vec4f(5.0, 6.0, 7.0, 8.0)]

        controller = og.Controller()
        keys = og.Controller.Keys

        (graph, (val0, val1, _, get_node), _, _) = controller.edit(
            self.TEST_GRAPH_PATH,
            {
                keys.CREATE_NODES: [
                    ("Val0", "omni.graph.nodes.ConstantFloat4"),
                    ("Val1", "omni.graph.nodes.ConstantFloat4"),
                    ("Array", "omni.graph.nodes.MakeArray"),
                    ("Get", "omni.graph.nodes.ReadOmniGraphValue"),
                ],
                keys.CONNECT: [
                    ("Val0.inputs:value", "Array.inputs:a"),
                    ("Val1.inputs:value", "Array.inputs:b"),
                ],
                keys.SET_VALUES: [
                    ("Array.inputs:arraySize", 2),
                    ("Val0.inputs:value", test_values[0]),
                    ("Val1.inputs:value", test_values[1]),
                    ("Get.inputs:path", f"{self.TEST_GRAPH_PATH}/Array"),
                    ("Get.inputs:name", "outputs:array"),
                ],
            },
        )
        await controller.evaluate(graph)

        out_controller = og.Controller(og.Controller.attribute("outputs:value", get_node))
        array = out_controller.get()
        self.assertEqual(array[0][0], test_values[0][0])
        self.assertEqual(array[0][1], test_values[0][1])
        self.assertEqual(array[0][2], test_values[0][2])
        self.assertEqual(array[0][3], test_values[0][3])
        self.assertEqual(array[1][0], test_values[1][0])
        self.assertEqual(array[1][1], test_values[1][1])
        self.assertEqual(array[1][2], test_values[1][2])
        self.assertEqual(array[1][3], test_values[1][3])

        # # try editing value
        test_values = [Gf.Vec4f(1.0, 2.0, 3.0, 4.0), Gf.Vec4f(5.0, 6.0, 7.0, 8.0)]
        og.Controller.attribute("inputs:value", val0).set(test_values[0])
        og.Controller.attribute("inputs:value", val1).set(test_values[1])
        await controller.evaluate(graph)
        array = out_controller.get()
        self.assertEqual(array[0][0], test_values[0][0])
        self.assertEqual(array[0][1], test_values[0][1])
        self.assertEqual(array[0][2], test_values[0][2])
        self.assertEqual(array[0][3], test_values[0][3])
        self.assertEqual(array[1][0], test_values[1][0])
        self.assertEqual(array[1][1], test_values[1][1])
        self.assertEqual(array[1][2], test_values[1][2])
        self.assertEqual(array[1][3], test_values[1][3])

    async def test_readomnigraphvalue_any(self):
        """Test ReadOmniGraphValue by reading from a constant node (any)"""

        test_value = 42

        controller = og.Controller()
        keys = og.Controller.Keys

        (graph, (var_node, _, get_node), _, _) = controller.edit(
            self.TEST_GRAPH_PATH,
            {
                keys.CREATE_NODES: [
                    ("Var", "omni.graph.nodes.ConstantInt"),
                    ("ToString", "omni.graph.nodes.ToString"),
                    ("Get", "omni.graph.nodes.ReadOmniGraphValue"),
                ],
                keys.CONNECT: [
                    ("Var.inputs:value", "ToString.inputs:value"),
                ],
                keys.SET_VALUES: [
                    ("Var.inputs:value", test_value),
                    ("Get.inputs:path", f"{self.TEST_GRAPH_PATH}/ToString"),
                    ("Get.inputs:name", "inputs:value"),
                ],
            },
        )
        await controller.evaluate(graph)

        out_controller = og.Controller(og.Controller.attribute("outputs:value", get_node))
        v = out_controller.get()
        self.assertEqual(v, test_value)

        # try editing value
        test_value = 1234
        og.Controller.attribute("inputs:value", var_node).set(test_value)
        await controller.evaluate(graph)
        v = out_controller.get()
        self.assertEqual(v, test_value)

    async def test_readomnigraphvalue_prim(self):
        """Test ReadOmniGraphValue by reading from a prim"""

        test_value = 555.0

        controller = og.Controller()
        keys = og.Controller.Keys

        # use ReadPrimAttribute node to cache the attribute into Fabric
        (graph, _, (prim,), _) = controller.edit(
            self.TEST_GRAPH_PATH,
            {
                keys.CREATE_NODES: [
                    ("ReadPrim", "omni.graph.nodes.ReadPrimAttribute"),
                ],
                keys.CREATE_PRIMS: ("/World/Float", {"myfloat": ("float", test_value)}),
                keys.SET_VALUES: [
                    ("ReadPrim.inputs:usePath", True),
                    ("ReadPrim.inputs:primPath", "/World/Float"),
                    ("ReadPrim.inputs:name", "myfloat"),
                ],
            },
        )
        await controller.evaluate(graph)

        (graph, (get_node,), _, _) = controller.edit(
            self.TEST_GRAPH_PATH,
            {
                keys.CREATE_NODES: [
                    ("Get", "omni.graph.nodes.ReadOmniGraphValue"),
                ],
                keys.SET_VALUES: [
                    ("Get.inputs:path", "/World/Float"),
                    ("Get.inputs:name", "myfloat"),
                ],
            },
        )
        await controller.evaluate(graph)

        out_controller = og.Controller(og.Controller.attribute("outputs:value", get_node))
        v = out_controller.get()
        self.assertEqual(v, test_value)

        # try editing value
        test_value = 42.0
        prim.GetProperty("myfloat").Set(test_value)
        await controller.evaluate(graph)
        v = out_controller.get()
        self.assertEqual(v, test_value)

    async def test_readomnigraphvalue_change_attribute(self):
        """Test ReadOmniGraphValue if attribute name is changed at runtime"""

        test_values = [42, 360]

        controller = og.Controller()
        keys = og.Controller.Keys

        (graph, (_, _, get_node), _, _) = controller.edit(
            self.TEST_GRAPH_PATH,
            {
                keys.CREATE_NODES: [
                    ("Var0", "omni.graph.nodes.ConstantInt"),
                    ("Var1", "omni.graph.nodes.ConstantInt"),
                    ("Get", "omni.graph.nodes.ReadOmniGraphValue"),
                ],
                keys.SET_VALUES: [
                    ("Var0.inputs:value", test_values[0]),
                    ("Var1.inputs:value", test_values[1]),
                    ("Get.inputs:path", f"{self.TEST_GRAPH_PATH}/Var0"),
                    ("Get.inputs:name", "inputs:value"),
                ],
            },
        )
        await controller.evaluate(graph)

        out_controller = og.Controller(og.Controller.attribute("outputs:value", get_node))
        v = out_controller.get()
        self.assertEqual(v, test_values[0])

        # try changing path
        og.Controller.attribute("inputs:path", get_node).set(f"{self.TEST_GRAPH_PATH}/Var1")
        await controller.evaluate(graph)
        v = out_controller.get()
        self.assertEqual(v, test_values[1])

    async def test_readomnigraphvalue_invalid(self):
        """Test ReadOmniGraphValue by reading something that is not in Fabric"""

        controller = og.Controller()
        keys = og.Controller.Keys

        (graph, (get_node,), _, _) = controller.edit(
            self.TEST_GRAPH_PATH,
            {
                keys.CREATE_NODES: [
                    ("Get", "omni.graph.nodes.ReadOmniGraphValue"),
                ],
                keys.CREATE_PRIMS: ("/World/Cube", "Cube"),
                keys.SET_VALUES: [
                    ("Get.inputs:path", "/World/Cube"),
                    ("Get.inputs:name", "xformOp:translate"),
                ],
            },
        )

        get_node.clear_old_compute_messages()
        with ogts.ExpectedError():
            await controller.evaluate(graph)
        self.assertEqual(len(get_node.get_compute_messages(og.WARNING)), 1)
