import os
import omni.kit.test
import omni.graph.core as og
import omni.graph.core.tests as ogts
from omni.graph.core.tests.omnigraph_test_utils import _TestGraphAndNode
from omni.graph.core.tests.omnigraph_test_utils import _test_clear_scene
from omni.graph.core.tests.omnigraph_test_utils import _test_setup_scene
from omni.graph.core.tests.omnigraph_test_utils import _test_verify_scene


class TestOgn(ogts.OmniGraphTestCase):

    TEST_DATA = [
        {
            'inputs': [
                ['inputs:a_color3d', [1.0, 2.0, 3.0], False],
                ['inputs:a_color3f', [11.0, 12.0, 13.0], False],
                ['inputs:a_color3h', [21.0, 22.0, 23.0], False],
                ['inputs:a_color4d', [1.0, 2.0, 3.0, 4.0], False],
                ['inputs:a_color4f', [11.0, 12.0, 13.0, 14.0], False],
                ['inputs:a_color4h', [21.0, 22.0, 23.0, 24.0], False],
                ['inputs:a_frame', [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0], False],
                ['inputs:a_matrix2d', [1.0, 2.0, 3.0, 4.0], False],
                ['inputs:a_matrix3d', [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], False],
                ['inputs:a_matrix4d', [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0], False],
                ['inputs:a_normal3d', [1.0, 2.0, 3.0], False],
                ['inputs:a_normal3f', [11.0, 12.0, 13.0], False],
                ['inputs:a_normal3h', [21.0, 22.0, 23.0], False],
                ['inputs:a_point3d', [1.0, 2.0, 3.0], False],
                ['inputs:a_point3f', [11.0, 12.0, 13.0], False],
                ['inputs:a_point3h', [21.0, 22.0, 23.0], False],
                ['inputs:a_quatd', [1.0, 2.0, 3.0, 4.0], False],
                ['inputs:a_quatf', [11.0, 12.0, 13.0, 14.0], False],
                ['inputs:a_quath', [21.0, 22.0, 23.0, 24.0], False],
                ['inputs:a_texcoord2d', [1.0, 2.0], False],
                ['inputs:a_texcoord2f', [11.0, 12.0], False],
                ['inputs:a_texcoord2h', [21.0, 22.0], False],
                ['inputs:a_texcoord3d', [1.0, 2.0, 3.0], False],
                ['inputs:a_texcoord3f', [11.0, 12.0, 13.0], False],
                ['inputs:a_texcoord3h', [21.0, 22.0, 23.0], False],
                ['inputs:a_timecode', 10.0, False],
                ['inputs:a_vector3d', [1.0, 2.0, 3.0], False],
                ['inputs:a_vector3f', [11.0, 12.0, 13.0], False],
                ['inputs:a_vector3h', [21.0, 22.0, 23.0], False],
            ],
            'outputs': [
                ['outputs:a_color3d', [2.0, 3.0, 4.0], False],
                ['outputs:a_color3f', [12.0, 13.0, 14.0], False],
                ['outputs:a_color3h', [22.0, 23.0, 24.0], False],
                ['outputs:a_color4d', [2.0, 3.0, 4.0, 5.0], False],
                ['outputs:a_color4f', [12.0, 13.0, 14.0, 15.0], False],
                ['outputs:a_color4h', [22.0, 23.0, 24.0, 25.0], False],
                ['outputs:a_frame', [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0], False],
                ['outputs:a_matrix2d', [2.0, 3.0, 4.0, 5.0], False],
                ['outputs:a_matrix3d', [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], False],
                ['outputs:a_matrix4d', [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0], False],
                ['outputs:a_normal3d', [2.0, 3.0, 4.0], False],
                ['outputs:a_normal3f', [12.0, 13.0, 14.0], False],
                ['outputs:a_normal3h', [22.0, 23.0, 24.0], False],
                ['outputs:a_point3d', [2.0, 3.0, 4.0], False],
                ['outputs:a_point3f', [12.0, 13.0, 14.0], False],
                ['outputs:a_point3h', [22.0, 23.0, 24.0], False],
                ['outputs:a_quatd', [2.0, 3.0, 4.0, 5.0], False],
                ['outputs:a_quatf', [12.0, 13.0, 14.0, 15.0], False],
                ['outputs:a_quath', [22.0, 23.0, 24.0, 25.0], False],
                ['outputs:a_texcoord2d', [2.0, 3.0], False],
                ['outputs:a_texcoord2f', [12.0, 13.0], False],
                ['outputs:a_texcoord2h', [22.0, 23.0], False],
                ['outputs:a_texcoord3d', [2.0, 3.0, 4.0], False],
                ['outputs:a_texcoord3f', [12.0, 13.0, 14.0], False],
                ['outputs:a_texcoord3h', [22.0, 23.0, 24.0], False],
                ['outputs:a_timecode', 11.0, False],
                ['outputs:a_vector3d', [2.0, 3.0, 4.0], False],
                ['outputs:a_vector3f', [12.0, 13.0, 14.0], False],
                ['outputs:a_vector3h', [22.0, 23.0, 24.0], False],
            ],
        },
    ]

    async def test_generated(self):
        test_info = _TestGraphAndNode()
        controller = og.Controller()
        for i, test_run in enumerate(self.TEST_DATA):
            await _test_clear_scene(self, test_run)
            test_info = await _test_setup_scene(self, controller, "/TestGraph", "TestNode_omni_graph_tutorials_RoleData", "omni.graph.tutorials.RoleData", test_run, test_info)
            await controller.evaluate(test_info.graph)
            _test_verify_scene(self, controller, test_run, test_info, f"omni.graph.tutorials.RoleData User test case #{i+1}")

    async def test_vectorized_generated(self):
        test_info = _TestGraphAndNode()
        controller = og.Controller()
        for i, test_run in enumerate(self.TEST_DATA):
            await _test_clear_scene(self, test_run)
            test_info = await _test_setup_scene(self, controller, "/TestGraph", "TestNode_omni_graph_tutorials_RoleData","omni.graph.tutorials.RoleData", test_run, test_info, 16)
            await controller.evaluate(test_info.graph)
            _test_verify_scene(self, controller, test_run, test_info, f"omni.graph.tutorials.RoleData User test case #{i+1}", 16)

    async def test_thread_safety(self):
        import omni.kit
        # Generate multiple instances of the test setup to run them concurrently
        instance_setup = dict()
        for n in range(24):
            instance_setup[f"/TestGraph_{n}"] = _TestGraphAndNode()

        for i, test_run in enumerate(self.TEST_DATA):
            await _test_clear_scene(self, test_run)
            for (key, test_info) in instance_setup.items():
                test_info = await _test_setup_scene(self, og.Controller(allow_exists_prim=True), key, "TestNode_omni_graph_tutorials_RoleData", "omni.graph.tutorials.RoleData", test_run, test_info)
            self.assertEqual(len(og.get_all_graphs()), 24)

            # We want to evaluate all graphs concurrently. Kick them all.
            # Evaluate multiple times to skip 2 serial frames and increase chances for a race condition.
            for _ in range(10):
                await omni.kit.app.get_app().next_update_async()

            for (key, test_instance) in instance_setup.items():
                _test_verify_scene(self, og.Controller(), test_run, test_info, f"omni.graph.tutorials.RoleData User test case #{i+1}, instance{key}")

async def test_data_access(self):
    from omni.graph.tutorials.ogn.OgnTutorialRoleDataDatabase import OgnTutorialRoleDataDatabase
    test_file_name = "OgnTutorialRoleDataTemplate.usda"
    usd_path = os.path.join(os.path.dirname(__file__), "usd", test_file_name)
    if not os.path.exists(usd_path):
        self.assertTrue(False, f"{usd_path} not found for loading test")
    (result, error) = await ogts.load_test_file(usd_path)
    self.assertTrue(result, f'{error} on {usd_path}')
    test_node = og.Controller.node("/TestGraph/Template_omni_graph_tutorials_RoleData")
    database = OgnTutorialRoleDataDatabase(test_node)
    self.assertTrue(test_node.is_valid())
    node_type_name = test_node.get_type_name()
    self.assertEqual(og.GraphRegistry().get_node_type_version(node_type_name), 1)

    def _attr_error(attribute: og.Attribute, usd_test: bool) -> str:
        test_type = "USD Load" if usd_test else "Database Access"
        return f"{node_type_name} {test_type} Test - {attribute.get_name()} value error"


    self.assertTrue(test_node.get_attribute_exists("inputs:a_color3d"))
    attribute = test_node.get_attribute("inputs:a_color3d")
    db_value = database.inputs.a_color3d
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_color3f"))
    attribute = test_node.get_attribute("inputs:a_color3f")
    db_value = database.inputs.a_color3f
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_color3h"))
    attribute = test_node.get_attribute("inputs:a_color3h")
    db_value = database.inputs.a_color3h
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_color4d"))
    attribute = test_node.get_attribute("inputs:a_color4d")
    db_value = database.inputs.a_color4d
    expected_value = [0.0, 0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_color4f"))
    attribute = test_node.get_attribute("inputs:a_color4f")
    db_value = database.inputs.a_color4f
    expected_value = [0.0, 0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_color4h"))
    attribute = test_node.get_attribute("inputs:a_color4h")
    db_value = database.inputs.a_color4h
    expected_value = [0.0, 0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_frame"))
    attribute = test_node.get_attribute("inputs:a_frame")
    db_value = database.inputs.a_frame
    expected_value = [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_matrix2d"))
    attribute = test_node.get_attribute("inputs:a_matrix2d")
    db_value = database.inputs.a_matrix2d
    expected_value = [[1.0, 0.0], [0.0, 1.0]]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_matrix3d"))
    attribute = test_node.get_attribute("inputs:a_matrix3d")
    db_value = database.inputs.a_matrix3d
    expected_value = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_matrix4d"))
    attribute = test_node.get_attribute("inputs:a_matrix4d")
    db_value = database.inputs.a_matrix4d
    expected_value = [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_normal3d"))
    attribute = test_node.get_attribute("inputs:a_normal3d")
    db_value = database.inputs.a_normal3d
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_normal3f"))
    attribute = test_node.get_attribute("inputs:a_normal3f")
    db_value = database.inputs.a_normal3f
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_normal3h"))
    attribute = test_node.get_attribute("inputs:a_normal3h")
    db_value = database.inputs.a_normal3h
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_point3d"))
    attribute = test_node.get_attribute("inputs:a_point3d")
    db_value = database.inputs.a_point3d
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_point3f"))
    attribute = test_node.get_attribute("inputs:a_point3f")
    db_value = database.inputs.a_point3f
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_point3h"))
    attribute = test_node.get_attribute("inputs:a_point3h")
    db_value = database.inputs.a_point3h
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_quatd"))
    attribute = test_node.get_attribute("inputs:a_quatd")
    db_value = database.inputs.a_quatd
    expected_value = [0.0, 0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_quatf"))
    attribute = test_node.get_attribute("inputs:a_quatf")
    db_value = database.inputs.a_quatf
    expected_value = [0.0, 0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_quath"))
    attribute = test_node.get_attribute("inputs:a_quath")
    db_value = database.inputs.a_quath
    expected_value = [0.0, 0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_texcoord2d"))
    attribute = test_node.get_attribute("inputs:a_texcoord2d")
    db_value = database.inputs.a_texcoord2d
    expected_value = [0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_texcoord2f"))
    attribute = test_node.get_attribute("inputs:a_texcoord2f")
    db_value = database.inputs.a_texcoord2f
    expected_value = [0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_texcoord2h"))
    attribute = test_node.get_attribute("inputs:a_texcoord2h")
    db_value = database.inputs.a_texcoord2h
    expected_value = [0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_texcoord3d"))
    attribute = test_node.get_attribute("inputs:a_texcoord3d")
    db_value = database.inputs.a_texcoord3d
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_texcoord3f"))
    attribute = test_node.get_attribute("inputs:a_texcoord3f")
    db_value = database.inputs.a_texcoord3f
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_texcoord3h"))
    attribute = test_node.get_attribute("inputs:a_texcoord3h")
    db_value = database.inputs.a_texcoord3h
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_timecode"))
    attribute = test_node.get_attribute("inputs:a_timecode")
    db_value = database.inputs.a_timecode
    expected_value = 1.0
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_vector3d"))
    attribute = test_node.get_attribute("inputs:a_vector3d")
    db_value = database.inputs.a_vector3d
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_vector3f"))
    attribute = test_node.get_attribute("inputs:a_vector3f")
    db_value = database.inputs.a_vector3f
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("inputs:a_vector3h"))
    attribute = test_node.get_attribute("inputs:a_vector3h")
    db_value = database.inputs.a_vector3h
    expected_value = [0.0, 0.0, 0.0]
    actual_value = og.Controller.get(attribute)
    ogts.verify_values(expected_value, actual_value, _attr_error(attribute, True))
    ogts.verify_values(expected_value, db_value, _attr_error(attribute, False))

    self.assertTrue(test_node.get_attribute_exists("outputs:a_color3d"))
    attribute = test_node.get_attribute("outputs:a_color3d")
    db_value = database.outputs.a_color3d

    self.assertTrue(test_node.get_attribute_exists("outputs:a_color3f"))
    attribute = test_node.get_attribute("outputs:a_color3f")
    db_value = database.outputs.a_color3f

    self.assertTrue(test_node.get_attribute_exists("outputs:a_color3h"))
    attribute = test_node.get_attribute("outputs:a_color3h")
    db_value = database.outputs.a_color3h

    self.assertTrue(test_node.get_attribute_exists("outputs:a_color4d"))
    attribute = test_node.get_attribute("outputs:a_color4d")
    db_value = database.outputs.a_color4d

    self.assertTrue(test_node.get_attribute_exists("outputs:a_color4f"))
    attribute = test_node.get_attribute("outputs:a_color4f")
    db_value = database.outputs.a_color4f

    self.assertTrue(test_node.get_attribute_exists("outputs:a_color4h"))
    attribute = test_node.get_attribute("outputs:a_color4h")
    db_value = database.outputs.a_color4h

    self.assertTrue(test_node.get_attribute_exists("outputs:a_frame"))
    attribute = test_node.get_attribute("outputs:a_frame")
    db_value = database.outputs.a_frame

    self.assertTrue(test_node.get_attribute_exists("outputs:a_matrix2d"))
    attribute = test_node.get_attribute("outputs:a_matrix2d")
    db_value = database.outputs.a_matrix2d

    self.assertTrue(test_node.get_attribute_exists("outputs:a_matrix3d"))
    attribute = test_node.get_attribute("outputs:a_matrix3d")
    db_value = database.outputs.a_matrix3d

    self.assertTrue(test_node.get_attribute_exists("outputs:a_matrix4d"))
    attribute = test_node.get_attribute("outputs:a_matrix4d")
    db_value = database.outputs.a_matrix4d

    self.assertTrue(test_node.get_attribute_exists("outputs:a_normal3d"))
    attribute = test_node.get_attribute("outputs:a_normal3d")
    db_value = database.outputs.a_normal3d

    self.assertTrue(test_node.get_attribute_exists("outputs:a_normal3f"))
    attribute = test_node.get_attribute("outputs:a_normal3f")
    db_value = database.outputs.a_normal3f

    self.assertTrue(test_node.get_attribute_exists("outputs:a_normal3h"))
    attribute = test_node.get_attribute("outputs:a_normal3h")
    db_value = database.outputs.a_normal3h

    self.assertTrue(test_node.get_attribute_exists("outputs:a_point3d"))
    attribute = test_node.get_attribute("outputs:a_point3d")
    db_value = database.outputs.a_point3d

    self.assertTrue(test_node.get_attribute_exists("outputs:a_point3f"))
    attribute = test_node.get_attribute("outputs:a_point3f")
    db_value = database.outputs.a_point3f

    self.assertTrue(test_node.get_attribute_exists("outputs:a_point3h"))
    attribute = test_node.get_attribute("outputs:a_point3h")
    db_value = database.outputs.a_point3h

    self.assertTrue(test_node.get_attribute_exists("outputs:a_quatd"))
    attribute = test_node.get_attribute("outputs:a_quatd")
    db_value = database.outputs.a_quatd

    self.assertTrue(test_node.get_attribute_exists("outputs:a_quatf"))
    attribute = test_node.get_attribute("outputs:a_quatf")
    db_value = database.outputs.a_quatf

    self.assertTrue(test_node.get_attribute_exists("outputs:a_quath"))
    attribute = test_node.get_attribute("outputs:a_quath")
    db_value = database.outputs.a_quath

    self.assertTrue(test_node.get_attribute_exists("outputs:a_texcoord2d"))
    attribute = test_node.get_attribute("outputs:a_texcoord2d")
    db_value = database.outputs.a_texcoord2d

    self.assertTrue(test_node.get_attribute_exists("outputs:a_texcoord2f"))
    attribute = test_node.get_attribute("outputs:a_texcoord2f")
    db_value = database.outputs.a_texcoord2f

    self.assertTrue(test_node.get_attribute_exists("outputs:a_texcoord2h"))
    attribute = test_node.get_attribute("outputs:a_texcoord2h")
    db_value = database.outputs.a_texcoord2h

    self.assertTrue(test_node.get_attribute_exists("outputs:a_texcoord3d"))
    attribute = test_node.get_attribute("outputs:a_texcoord3d")
    db_value = database.outputs.a_texcoord3d

    self.assertTrue(test_node.get_attribute_exists("outputs:a_texcoord3f"))
    attribute = test_node.get_attribute("outputs:a_texcoord3f")
    db_value = database.outputs.a_texcoord3f

    self.assertTrue(test_node.get_attribute_exists("outputs:a_texcoord3h"))
    attribute = test_node.get_attribute("outputs:a_texcoord3h")
    db_value = database.outputs.a_texcoord3h

    self.assertTrue(test_node.get_attribute_exists("outputs:a_timecode"))
    attribute = test_node.get_attribute("outputs:a_timecode")
    db_value = database.outputs.a_timecode

    self.assertTrue(test_node.get_attribute_exists("outputs:a_vector3d"))
    attribute = test_node.get_attribute("outputs:a_vector3d")
    db_value = database.outputs.a_vector3d

    self.assertTrue(test_node.get_attribute_exists("outputs:a_vector3f"))
    attribute = test_node.get_attribute("outputs:a_vector3f")
    db_value = database.outputs.a_vector3f

    self.assertTrue(test_node.get_attribute_exists("outputs:a_vector3h"))
    attribute = test_node.get_attribute("outputs:a_vector3h")
    db_value = database.outputs.a_vector3h
