|  | 
| 12 | 12 | # See the License for the specific language governing permissions and | 
| 13 | 13 | # limitations under the License. | 
| 14 | 14 | 
 | 
|  | 15 | +from pprint import pformat | 
| 15 | 16 | import collections | 
| 16 | 17 | import datetime | 
| 17 | 18 | import decimal | 
|  | 19 | +import logging | 
| 18 | 20 | import math | 
| 19 | 21 | import operator | 
| 20 | 22 | import os | 
| 21 | 23 | import struct | 
|  | 24 | +import sys | 
| 22 | 25 | import threading | 
| 23 | 26 | import time | 
| 24 | 27 | import unittest | 
|  | 
| 52 | 55 | from tests._helpers import OpenTelemetryBase, HAS_OPENTELEMETRY_INSTALLED | 
| 53 | 56 | 
 | 
| 54 | 57 | 
 | 
|  | 58 | +logger = logging.getLogger(__name__) | 
|  | 59 | +logger.addHandler(logging.StreamHandler(sys.stderr)) | 
|  | 60 | +logger.setLevel(logging.INFO) | 
|  | 61 | + | 
|  | 62 | + | 
| 55 | 63 | CREATE_INSTANCE = os.getenv("GOOGLE_CLOUD_TESTS_CREATE_SPANNER_INSTANCE") is not None | 
| 56 | 64 | USE_EMULATOR = os.getenv("SPANNER_EMULATOR_HOST") is not None | 
| 57 | 65 | SKIP_BACKUP_TESTS = os.getenv("SKIP_BACKUP_TESTS") is not None | 
| @@ -905,43 +913,63 @@ def test_batch_insert_then_read(self): | 
| 905 | 913 | 
 | 
| 906 | 914 |         if HAS_OPENTELEMETRY_INSTALLED: | 
| 907 | 915 |             span_list = self.memory_exporter.get_finished_spans() | 
| 908 |  | -            self.assertEqual(len(span_list), 4) | 
| 909 |  | -            self.assertSpanAttributes( | 
| 910 |  | -                "CloudSpanner.GetSession", | 
| 911 |  | -                attributes=dict( | 
| 912 |  | -                    BASE_ATTRIBUTES, | 
| 913 |  | -                    **{"db.instance": self._db.name, "session_found": True} | 
| 914 |  | -                ), | 
| 915 |  | -                span=span_list[0], | 
| 916 |  | -            ) | 
| 917 |  | -            self.assertSpanAttributes( | 
| 918 |  | -                "CloudSpanner.Commit", | 
| 919 |  | -                attributes=dict( | 
| 920 |  | -                    BASE_ATTRIBUTES, | 
| 921 |  | -                    **{"db.instance": self._db.name, "num_mutations": 2} | 
| 922 |  | -                ), | 
| 923 |  | -                span=span_list[1], | 
| 924 |  | -            ) | 
| 925 |  | -            self.assertSpanAttributes( | 
| 926 |  | -                "CloudSpanner.GetSession", | 
| 927 |  | -                attributes=dict( | 
| 928 |  | -                    BASE_ATTRIBUTES, | 
| 929 |  | -                    **{"db.instance": self._db.name, "session_found": True} | 
| 930 |  | -                ), | 
| 931 |  | -                span=span_list[2], | 
| 932 |  | -            ) | 
| 933 |  | -            self.assertSpanAttributes( | 
| 934 |  | -                "CloudSpanner.ReadOnlyTransaction", | 
| 935 |  | -                attributes=dict( | 
| 936 |  | -                    BASE_ATTRIBUTES, | 
| 937 |  | -                    **{ | 
| 938 |  | -                        "db.instance": self._db.name, | 
| 939 |  | -                        "columns": self.COLUMNS, | 
| 940 |  | -                        "table_id": self.TABLE, | 
| 941 |  | -                    } | 
| 942 |  | -                ), | 
| 943 |  | -                span=span_list[3], | 
| 944 |  | -            ) | 
|  | 916 | +            try: | 
|  | 917 | +                self.assertEqual(len(span_list), 4) | 
|  | 918 | +            except AssertionError: | 
|  | 919 | +                logger.error(pformat(span_list)) | 
|  | 920 | +                raise | 
|  | 921 | +            try: | 
|  | 922 | +                self.assertSpanAttributes( | 
|  | 923 | +                    "CloudSpanner.GetSession", | 
|  | 924 | +                    attributes=dict( | 
|  | 925 | +                        BASE_ATTRIBUTES, | 
|  | 926 | +                        **{"db.instance": self._db.name, "session_found": True} | 
|  | 927 | +                    ), | 
|  | 928 | +                    span=span_list[0], | 
|  | 929 | +                ) | 
|  | 930 | +            except AssertionError: | 
|  | 931 | +                logger.error(pformat(span_list)) | 
|  | 932 | +                raise | 
|  | 933 | +            try: | 
|  | 934 | +                self.assertSpanAttributes( | 
|  | 935 | +                    "CloudSpanner.Commit", | 
|  | 936 | +                    attributes=dict( | 
|  | 937 | +                        BASE_ATTRIBUTES, | 
|  | 938 | +                        **{"db.instance": self._db.name, "num_mutations": 2} | 
|  | 939 | +                    ), | 
|  | 940 | +                    span=span_list[1], | 
|  | 941 | +                ) | 
|  | 942 | +            except AssertionError: | 
|  | 943 | +                logger.error(pformat(span_list)) | 
|  | 944 | +                raise | 
|  | 945 | +            try: | 
|  | 946 | +                self.assertSpanAttributes( | 
|  | 947 | +                    "CloudSpanner.GetSession", | 
|  | 948 | +                    attributes=dict( | 
|  | 949 | +                        BASE_ATTRIBUTES, | 
|  | 950 | +                        **{"db.instance": self._db.name, "session_found": True} | 
|  | 951 | +                    ), | 
|  | 952 | +                    span=span_list[2], | 
|  | 953 | +                ) | 
|  | 954 | +            except AssertionError: | 
|  | 955 | +                logger.error(pformat(span_list)) | 
|  | 956 | +                raise | 
|  | 957 | +            try: | 
|  | 958 | +                self.assertSpanAttributes( | 
|  | 959 | +                    "CloudSpanner.ReadOnlyTransaction", | 
|  | 960 | +                    attributes=dict( | 
|  | 961 | +                        BASE_ATTRIBUTES, | 
|  | 962 | +                        **{ | 
|  | 963 | +                            "db.instance": self._db.name, | 
|  | 964 | +                            "columns": self.COLUMNS, | 
|  | 965 | +                            "table_id": self.TABLE, | 
|  | 966 | +                        } | 
|  | 967 | +                    ), | 
|  | 968 | +                    span=span_list[3], | 
|  | 969 | +                ) | 
|  | 970 | +            except AssertionError: | 
|  | 971 | +                logger.error(pformat(span_list)) | 
|  | 972 | +                raise | 
| 945 | 973 | 
 | 
| 946 | 974 |     def test_batch_insert_then_read_string_array_of_string(self): | 
| 947 | 975 |         TABLE = "string_plus_array_of_string" | 
| @@ -1049,74 +1077,110 @@ def test_transaction_read_and_insert_then_rollback(self): | 
| 1049 | 1077 | 
 | 
| 1050 | 1078 |         if HAS_OPENTELEMETRY_INSTALLED: | 
| 1051 | 1079 |             span_list = self.memory_exporter.get_finished_spans() | 
| 1052 |  | -            self.assertEqual(len(span_list), 8) | 
| 1053 |  | -            self.assertSpanAttributes( | 
| 1054 |  | -                "CloudSpanner.CreateSession", | 
| 1055 |  | -                attributes=dict(BASE_ATTRIBUTES, **{"db.instance": self._db.name}), | 
| 1056 |  | -                span=span_list[0], | 
| 1057 |  | -            ) | 
| 1058 |  | -            self.assertSpanAttributes( | 
| 1059 |  | -                "CloudSpanner.GetSession", | 
| 1060 |  | -                attributes=dict( | 
| 1061 |  | -                    BASE_ATTRIBUTES, | 
| 1062 |  | -                    **{"db.instance": self._db.name, "session_found": True} | 
| 1063 |  | -                ), | 
| 1064 |  | -                span=span_list[1], | 
| 1065 |  | -            ) | 
| 1066 |  | -            self.assertSpanAttributes( | 
| 1067 |  | -                "CloudSpanner.Commit", | 
| 1068 |  | -                attributes=dict( | 
| 1069 |  | -                    BASE_ATTRIBUTES, | 
| 1070 |  | -                    **{"db.instance": self._db.name, "num_mutations": 1} | 
| 1071 |  | -                ), | 
| 1072 |  | -                span=span_list[2], | 
| 1073 |  | -            ) | 
| 1074 |  | -            self.assertSpanAttributes( | 
| 1075 |  | -                "CloudSpanner.BeginTransaction", | 
| 1076 |  | -                attributes=dict(BASE_ATTRIBUTES, **{"db.instance": self._db.name}), | 
| 1077 |  | -                span=span_list[3], | 
| 1078 |  | -            ) | 
| 1079 |  | -            self.assertSpanAttributes( | 
| 1080 |  | -                "CloudSpanner.ReadOnlyTransaction", | 
| 1081 |  | -                attributes=dict( | 
| 1082 |  | -                    BASE_ATTRIBUTES, | 
| 1083 |  | -                    **{ | 
| 1084 |  | -                        "db.instance": self._db.name, | 
| 1085 |  | -                        "table_id": self.TABLE, | 
| 1086 |  | -                        "columns": self.COLUMNS, | 
| 1087 |  | -                    } | 
| 1088 |  | -                ), | 
| 1089 |  | -                span=span_list[4], | 
| 1090 |  | -            ) | 
| 1091 |  | -            self.assertSpanAttributes( | 
| 1092 |  | -                "CloudSpanner.ReadOnlyTransaction", | 
| 1093 |  | -                attributes=dict( | 
| 1094 |  | -                    BASE_ATTRIBUTES, | 
| 1095 |  | -                    **{ | 
| 1096 |  | -                        "db.instance": self._db.name, | 
| 1097 |  | -                        "table_id": self.TABLE, | 
| 1098 |  | -                        "columns": self.COLUMNS, | 
| 1099 |  | -                    } | 
| 1100 |  | -                ), | 
| 1101 |  | -                span=span_list[5], | 
| 1102 |  | -            ) | 
| 1103 |  | -            self.assertSpanAttributes( | 
| 1104 |  | -                "CloudSpanner.Rollback", | 
| 1105 |  | -                attributes=dict(BASE_ATTRIBUTES, **{"db.instance": self._db.name}), | 
| 1106 |  | -                span=span_list[6], | 
| 1107 |  | -            ) | 
| 1108 |  | -            self.assertSpanAttributes( | 
| 1109 |  | -                "CloudSpanner.ReadOnlyTransaction", | 
| 1110 |  | -                attributes=dict( | 
| 1111 |  | -                    BASE_ATTRIBUTES, | 
| 1112 |  | -                    **{ | 
| 1113 |  | -                        "db.instance": self._db.name, | 
| 1114 |  | -                        "table_id": self.TABLE, | 
| 1115 |  | -                        "columns": self.COLUMNS, | 
| 1116 |  | -                    } | 
| 1117 |  | -                ), | 
| 1118 |  | -                span=span_list[7], | 
| 1119 |  | -            ) | 
|  | 1080 | +            try: | 
|  | 1081 | +                self.assertEqual(len(span_list), 8) | 
|  | 1082 | +            except AssertionError: | 
|  | 1083 | +                logger.error(pformat(span_list)) | 
|  | 1084 | +                raise | 
|  | 1085 | +            try: | 
|  | 1086 | +                self.assertSpanAttributes( | 
|  | 1087 | +                    "CloudSpanner.CreateSession", | 
|  | 1088 | +                    attributes=dict(BASE_ATTRIBUTES, **{"db.instance": self._db.name}), | 
|  | 1089 | +                    span=span_list[0], | 
|  | 1090 | +                ) | 
|  | 1091 | +            except AssertionError: | 
|  | 1092 | +                logger.error(pformat(span_list)) | 
|  | 1093 | +                raise | 
|  | 1094 | +            try: | 
|  | 1095 | +                self.assertSpanAttributes( | 
|  | 1096 | +                    "CloudSpanner.GetSession", | 
|  | 1097 | +                    attributes=dict( | 
|  | 1098 | +                        BASE_ATTRIBUTES, | 
|  | 1099 | +                        **{"db.instance": self._db.name, "session_found": True} | 
|  | 1100 | +                    ), | 
|  | 1101 | +                    span=span_list[1], | 
|  | 1102 | +                ) | 
|  | 1103 | +            except AssertionError: | 
|  | 1104 | +                logger.error(pformat(span_list)) | 
|  | 1105 | +                raise | 
|  | 1106 | +            try: | 
|  | 1107 | +                self.assertSpanAttributes( | 
|  | 1108 | +                    "CloudSpanner.Commit", | 
|  | 1109 | +                    attributes=dict( | 
|  | 1110 | +                        BASE_ATTRIBUTES, | 
|  | 1111 | +                        **{"db.instance": self._db.name, "num_mutations": 1} | 
|  | 1112 | +                    ), | 
|  | 1113 | +                    span=span_list[2], | 
|  | 1114 | +                ) | 
|  | 1115 | +            except AssertionError: | 
|  | 1116 | +                logger.error(pformat(span_list)) | 
|  | 1117 | +                raise | 
|  | 1118 | +            try: | 
|  | 1119 | +                self.assertSpanAttributes( | 
|  | 1120 | +                    "CloudSpanner.BeginTransaction", | 
|  | 1121 | +                    attributes=dict(BASE_ATTRIBUTES, **{"db.instance": self._db.name}), | 
|  | 1122 | +                    span=span_list[3], | 
|  | 1123 | +                ) | 
|  | 1124 | +            except AssertionError: | 
|  | 1125 | +                logger.error(pformat(span_list)) | 
|  | 1126 | +                raise | 
|  | 1127 | +            try: | 
|  | 1128 | +                self.assertSpanAttributes( | 
|  | 1129 | +                    "CloudSpanner.ReadOnlyTransaction", | 
|  | 1130 | +                    attributes=dict( | 
|  | 1131 | +                        BASE_ATTRIBUTES, | 
|  | 1132 | +                        **{ | 
|  | 1133 | +                            "db.instance": self._db.name, | 
|  | 1134 | +                            "table_id": self.TABLE, | 
|  | 1135 | +                            "columns": self.COLUMNS, | 
|  | 1136 | +                        } | 
|  | 1137 | +                    ), | 
|  | 1138 | +                    span=span_list[4], | 
|  | 1139 | +                ) | 
|  | 1140 | +            except AssertionError: | 
|  | 1141 | +                logger.error(pformat(span_list)) | 
|  | 1142 | +                raise | 
|  | 1143 | +            try: | 
|  | 1144 | +                self.assertSpanAttributes( | 
|  | 1145 | +                    "CloudSpanner.ReadOnlyTransaction", | 
|  | 1146 | +                    attributes=dict( | 
|  | 1147 | +                        BASE_ATTRIBUTES, | 
|  | 1148 | +                        **{ | 
|  | 1149 | +                            "db.instance": self._db.name, | 
|  | 1150 | +                            "table_id": self.TABLE, | 
|  | 1151 | +                            "columns": self.COLUMNS, | 
|  | 1152 | +                        } | 
|  | 1153 | +                    ), | 
|  | 1154 | +                    span=span_list[5], | 
|  | 1155 | +                ) | 
|  | 1156 | +            except AssertionError: | 
|  | 1157 | +                logger.error(pformat(span_list)) | 
|  | 1158 | +                raise | 
|  | 1159 | +            try: | 
|  | 1160 | +                self.assertSpanAttributes( | 
|  | 1161 | +                    "CloudSpanner.Rollback", | 
|  | 1162 | +                    attributes=dict(BASE_ATTRIBUTES, **{"db.instance": self._db.name}), | 
|  | 1163 | +                    span=span_list[6], | 
|  | 1164 | +                ) | 
|  | 1165 | +            except AssertionError: | 
|  | 1166 | +                logger.error(pformat(span_list)) | 
|  | 1167 | +                raise | 
|  | 1168 | +            try: | 
|  | 1169 | +                self.assertSpanAttributes( | 
|  | 1170 | +                    "CloudSpanner.ReadOnlyTransaction", | 
|  | 1171 | +                    attributes=dict( | 
|  | 1172 | +                        BASE_ATTRIBUTES, | 
|  | 1173 | +                        **{ | 
|  | 1174 | +                            "db.instance": self._db.name, | 
|  | 1175 | +                            "table_id": self.TABLE, | 
|  | 1176 | +                            "columns": self.COLUMNS, | 
|  | 1177 | +                        } | 
|  | 1178 | +                    ), | 
|  | 1179 | +                    span=span_list[7], | 
|  | 1180 | +                ) | 
|  | 1181 | +            except AssertionError: | 
|  | 1182 | +                logger.error(pformat(span_list)) | 
|  | 1183 | +                raise | 
| 1120 | 1184 | 
 | 
| 1121 | 1185 |     def _transaction_read_then_raise(self, transaction): | 
| 1122 | 1186 |         rows = list(transaction.read(self.TABLE, self.COLUMNS, self.ALL)) | 
| @@ -1464,21 +1528,33 @@ def unit_of_work(transaction, self): | 
| 1464 | 1528 |             session.run_in_transaction(unit_of_work, self) | 
| 1465 | 1529 | 
 | 
| 1466 | 1530 |         span_list = self.memory_exporter.get_finished_spans() | 
| 1467 |  | -        self.assertEqual(len(span_list), 6) | 
| 1468 |  | -        self.assertEqual( | 
| 1469 |  | -            list(map(lambda span: span.name, span_list)), | 
| 1470 |  | -            [ | 
| 1471 |  | -                "CloudSpanner.CreateSession", | 
| 1472 |  | -                "CloudSpanner.Commit", | 
| 1473 |  | -                "CloudSpanner.BeginTransaction", | 
| 1474 |  | -                "CloudSpanner.DMLTransaction", | 
| 1475 |  | -                "CloudSpanner.Commit", | 
| 1476 |  | -                "Test Span", | 
| 1477 |  | -            ], | 
| 1478 |  | -        ) | 
| 1479 |  | -        for span in span_list[2:-1]: | 
| 1480 |  | -            self.assertEqual(span.context.trace_id, span_list[-1].context.trace_id) | 
| 1481 |  | -            self.assertEqual(span.parent.span_id, span_list[-1].context.span_id) | 
|  | 1531 | +        try: | 
|  | 1532 | +            self.assertEqual(len(span_list), 6) | 
|  | 1533 | +        except AssertionError: | 
|  | 1534 | +            logger.error(pformat(span_list)) | 
|  | 1535 | +            raise | 
|  | 1536 | +        try: | 
|  | 1537 | +            self.assertEqual( | 
|  | 1538 | +                list(map(lambda span: span.name, span_list)), | 
|  | 1539 | +                [ | 
|  | 1540 | +                    "CloudSpanner.CreateSession", | 
|  | 1541 | +                    "CloudSpanner.Commit", | 
|  | 1542 | +                    "CloudSpanner.BeginTransaction", | 
|  | 1543 | +                    "CloudSpanner.DMLTransaction", | 
|  | 1544 | +                    "CloudSpanner.Commit", | 
|  | 1545 | +                    "Test Span", | 
|  | 1546 | +                ], | 
|  | 1547 | +            ) | 
|  | 1548 | +        except AssertionError: | 
|  | 1549 | +            logger.error(pformat(span_list)) | 
|  | 1550 | +            raise | 
|  | 1551 | +        try: | 
|  | 1552 | +            for span in span_list[2:-1]: | 
|  | 1553 | +                self.assertEqual(span.context.trace_id, span_list[-1].context.trace_id) | 
|  | 1554 | +                self.assertEqual(span.parent.span_id, span_list[-1].context.span_id) | 
|  | 1555 | +        except AssertionError: | 
|  | 1556 | +            logger.error(pformat(span_list)) | 
|  | 1557 | +            raise | 
| 1482 | 1558 | 
 | 
| 1483 | 1559 |     def test_execute_partitioned_dml(self): | 
| 1484 | 1560 |         # [START spanner_test_dml_partioned_dml_update] | 
|  | 
0 commit comments