Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package 
python-opentelemetry-exporter-otlp-proto-grpc for openSUSE:Factory checked in 
at 2024-09-06 17:18:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing 
/work/SRC/openSUSE:Factory/python-opentelemetry-exporter-otlp-proto-grpc (Old)
 and      
/work/SRC/openSUSE:Factory/.python-opentelemetry-exporter-otlp-proto-grpc.new.10096
 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-opentelemetry-exporter-otlp-proto-grpc"

Fri Sep  6 17:18:15 2024 rev:5 rq:1199129 version:1.27.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-opentelemetry-exporter-otlp-proto-grpc/python-opentelemetry-exporter-otlp-proto-grpc.changes
      2024-06-19 16:37:04.802461447 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-opentelemetry-exporter-otlp-proto-grpc.new.10096/python-opentelemetry-exporter-otlp-proto-grpc.changes
   2024-09-06 17:18:31.255831378 +0200
@@ -1,0 +2,22 @@
+Wed Sep  4 21:24:14 UTC 2024 - Guang Yee <g...@suse.com>
+
+- update to 1.27.0:
+  * Implementation of Events API
+  * Make log sdk add exception.message to logRecord for exceptions whose 
argument is an exception not a string message
+  * Fix use of link.attributes.dropped, which may not exist
+  * Running mypy on SDK resources
+  * Added py.typed file to top-level module
+  * Drop Final annotation from Enum in semantic conventions
+  * Update log export example to not use root logger
+  * Update semantic conventions to version 1.27.0
+  * Add support to type bytes for OTLP AnyValue
+  * Export ExponentialHistogram and ExponentialHistogramDataPoint
+  * Implement Client Key and Certificate File Support for All OTLP Exporters
+  * Remove _start_time_unix_nano attribute from _ViewInstrumentMatch in favor 
of using time_ns() at the moment when the aggregation object is created
+
+-------------------------------------------------------------------
+Tue Aug 27 17:04:39 UTC 2024 - Guang Yee <g...@suse.com>
+
+- Enable sle15_python_module_pythons
+
+-------------------------------------------------------------------

Old:
----
  opentelemetry_exporter_otlp_proto_grpc-1.25.0.tar.gz

New:
----
  opentelemetry_exporter_otlp_proto_grpc-1.27.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-opentelemetry-exporter-otlp-proto-grpc.spec ++++++
--- /var/tmp/diff_new_pack.asy4ey/_old  2024-09-06 17:18:31.731851156 +0200
+++ /var/tmp/diff_new_pack.asy4ey/_new  2024-09-06 17:18:31.731851156 +0200
@@ -16,8 +16,9 @@
 #
 
 
+%{?sle15_python_module_pythons}
 Name:           python-opentelemetry-exporter-otlp-proto-grpc
-Version:        1.25.0
+Version:        1.27.0
 Release:        0
 Summary:        OpenTelemetry Collector Protobuf over gRPC Exporter
 License:        Apache-2.0
@@ -33,9 +34,10 @@
 BuildRequires:  %{python_module opentelemetry-api >= 1.15}
 BuildRequires:  %{python_module opentelemetry-exporter-otlp-proto-common = 
%{version}}
 BuildRequires:  %{python_module opentelemetry-proto = %{version}}
-BuildRequires:  %{python_module opentelemetry-sdk >= 1.23.0}
+BuildRequires:  %{python_module opentelemetry-sdk >= 1.27.0}
 BuildRequires:  %{python_module opentelemetry-test-utils}
 BuildRequires:  %{python_module pytest-grpc}
+BuildRequires:  %{python_module requests}
 # /SECTION
 BuildRequires:  fdupes
 Requires:       python-Deprecated >= 1.2.6

++++++ opentelemetry_exporter_otlp_proto_grpc-1.25.0.tar.gz -> 
opentelemetry_exporter_otlp_proto_grpc-1.27.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/.gitignore 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/.gitignore
--- old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/.gitignore        
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/.gitignore        
2020-02-02 01:00:00.000000000 +0100
@@ -66,3 +66,6 @@
 
 # Semantic conventions
 scripts/semconv/semantic-conventions
+
+# Benchmark result files
+*-benchmark.json
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/PKG-INFO 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/PKG-INFO
--- old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/PKG-INFO  2020-02-02 
01:00:00.000000000 +0100
+++ new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/PKG-INFO  2020-02-02 
01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.3
 Name: opentelemetry-exporter-otlp-proto-grpc
-Version: 1.25.0
+Version: 1.27.0
 Summary: OpenTelemetry Collector Protobuf over gRPC Exporter
 Project-URL: Homepage, 
https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-proto-grpc
 Author-email: OpenTelemetry Authors 
<cncf-opentelemetry-contribut...@lists.cncf.io>
@@ -17,14 +17,15 @@
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
 Requires-Python: >=3.8
 Requires-Dist: deprecated>=1.2.6
 Requires-Dist: googleapis-common-protos~=1.52
 Requires-Dist: grpcio<2.0.0,>=1.0.0
 Requires-Dist: opentelemetry-api~=1.15
-Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.25.0
-Requires-Dist: opentelemetry-proto==1.25.0
-Requires-Dist: opentelemetry-sdk~=1.25.0
+Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.27.0
+Requires-Dist: opentelemetry-proto==1.27.0
+Requires-Dist: opentelemetry-sdk~=1.27.0
 Description-Content-Type: text/x-rst
 
 OpenTelemetry Collector Protobuf over gRPC Exporter
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/pyproject.toml 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/pyproject.toml
--- old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/pyproject.toml    
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/pyproject.toml    
2020-02-02 01:00:00.000000000 +0100
@@ -24,15 +24,16 @@
   "Programming Language :: Python :: 3.9",
   "Programming Language :: Python :: 3.10",
   "Programming Language :: Python :: 3.11",
+  "Programming Language :: Python :: 3.12",
 ]
 dependencies = [
   "Deprecated >= 1.2.6",
   "googleapis-common-protos ~= 1.52",
   "grpcio >= 1.0.0, < 2.0.0",
   "opentelemetry-api ~= 1.15",
-  "opentelemetry-proto == 1.25.0",
-  "opentelemetry-sdk ~= 1.25.0",
-  "opentelemetry-exporter-otlp-proto-common == 1.25.0",
+  "opentelemetry-proto == 1.27.0",
+  "opentelemetry-sdk ~= 1.27.0",
+  "opentelemetry-exporter-otlp-proto-common == 1.27.0",
 ]
 
 [project.entry-points.opentelemetry_logs_exporter]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py
      2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py
      2020-02-02 01:00:00.000000000 +0100
@@ -34,6 +34,8 @@
 
 from opentelemetry.sdk.environment_variables import (
     OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE,
+    OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE,
+    OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY,
     OTEL_EXPORTER_OTLP_LOGS_COMPRESSION,
     OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
     OTEL_EXPORTER_OTLP_LOGS_HEADERS,
@@ -71,7 +73,10 @@
             and environ.get(OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE) is not None
         ):
             credentials = _get_credentials(
-                credentials, OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE
+                credentials,
+                OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE,
+                OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY,
+                OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE,
             )
 
         environ_timeout = environ.get(OTEL_EXPORTER_OTLP_LOGS_TIMEOUT)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py
    2020-02-02 01:00:00.000000000 +0100
@@ -61,6 +61,8 @@
 )
 from opentelemetry.proto.resource.v1.resource_pb2 import Resource  # noqa: F401
 from opentelemetry.sdk.environment_variables import (
+    OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE,
+    OTEL_EXPORTER_OTLP_CLIENT_KEY,
     OTEL_EXPORTER_OTLP_CERTIFICATE,
     OTEL_EXPORTER_OTLP_COMPRESSION,
     OTEL_EXPORTER_OTLP_ENDPOINT,
@@ -118,22 +120,55 @@
     return _get_resource_data(sdk_resource_scope_data, resource_class, name)
 
 
-def _load_credential_from_file(filepath) -> ChannelCredentials:
+def _read_file(file_path: str) -> Optional[bytes]:
     try:
-        with open(filepath, "rb") as creds_file:
-            credential = creds_file.read()
-            return ssl_channel_credentials(credential)
-    except FileNotFoundError:
-        logger.exception("Failed to read credential file")
+        with open(file_path, "rb") as file:
+            return file.read()
+    except FileNotFoundError as e:
+        logger.exception(
+            f"Failed to read file: {e.filename}. Please check if the file 
exists and is accessible."
+        )
         return None
 
 
-def _get_credentials(creds, environ_key):
+def _load_credentials(
+    certificate_file: Optional[str],
+    client_key_file: Optional[str],
+    client_certificate_file: Optional[str],
+) -> Optional[ChannelCredentials]:
+    root_certificates = (
+        _read_file(certificate_file) if certificate_file else None
+    )
+    private_key = _read_file(client_key_file) if client_key_file else None
+    certificate_chain = (
+        _read_file(client_certificate_file)
+        if client_certificate_file
+        else None
+    )
+
+    return ssl_channel_credentials(
+        root_certificates=root_certificates,
+        private_key=private_key,
+        certificate_chain=certificate_chain,
+    )
+
+
+def _get_credentials(
+    creds: Optional[ChannelCredentials],
+    certificate_file_env_key: str,
+    client_key_file_env_key: str,
+    client_certificate_file_env_key: str,
+) -> ChannelCredentials:
     if creds is not None:
         return creds
-    creds_env = environ.get(environ_key)
-    if creds_env:
-        return _load_credential_from_file(creds_env)
+
+    certificate_file = environ.get(certificate_file_env_key)
+    if certificate_file:
+        client_key_file = environ.get(client_key_file_env_key)
+        client_certificate_file = environ.get(client_certificate_file_env_key)
+        return _load_credentials(
+            certificate_file, client_key_file, client_certificate_file
+        )
     return ssl_channel_credentials()
 
 
@@ -188,7 +223,7 @@
 
         self._headers = headers or environ.get(OTEL_EXPORTER_OTLP_HEADERS)
         if isinstance(self._headers, str):
-            temp_headers = parse_env_headers(self._headers)
+            temp_headers = parse_env_headers(self._headers, liberal=True)
             self._headers = tuple(temp_headers.items())
         elif isinstance(self._headers, dict):
             self._headers = tuple(self._headers.items())
@@ -214,7 +249,10 @@
             )
         else:
             credentials = _get_credentials(
-                credentials, OTEL_EXPORTER_OTLP_CERTIFICATE
+                credentials,
+                OTEL_EXPORTER_OTLP_CERTIFICATE,
+                OTEL_EXPORTER_OTLP_CLIENT_KEY,
+                OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE,
             )
             self._client = self._stub(
                 secure_channel(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/src/opentelemetry/exporter/otlp/proto/grpc/metric_exporter/__init__.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/src/opentelemetry/exporter/otlp/proto/grpc/metric_exporter/__init__.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/src/opentelemetry/exporter/otlp/proto/grpc/metric_exporter/__init__.py
    2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/src/opentelemetry/exporter/otlp/proto/grpc/metric_exporter/__init__.py
    2020-02-02 01:00:00.000000000 +0100
@@ -42,6 +42,8 @@
 from opentelemetry.proto.metrics.v1 import metrics_pb2 as pb2  # noqa: F401
 from opentelemetry.sdk.environment_variables import (
     OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE,
+    OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE,
+    OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY,
     OTEL_EXPORTER_OTLP_METRICS_COMPRESSION,
     OTEL_EXPORTER_OTLP_METRICS_ENDPOINT,
     OTEL_EXPORTER_OTLP_METRICS_HEADERS,
@@ -113,7 +115,10 @@
             and environ.get(OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE) is not None
         ):
             credentials = _get_credentials(
-                credentials, OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE
+                credentials,
+                OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE,
+                OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY,
+                OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE,
             )
 
         environ_timeout = environ.get(OTEL_EXPORTER_OTLP_METRICS_TIMEOUT)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py
     2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py
     2020-02-02 01:00:00.000000000 +0100
@@ -48,6 +48,8 @@
 )
 from opentelemetry.proto.trace.v1.trace_pb2 import Status  # noqa: F401
 from opentelemetry.sdk.environment_variables import (
+    OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE,
+    OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY,
     OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE,
     OTEL_EXPORTER_OTLP_TRACES_COMPRESSION,
     OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
@@ -105,7 +107,10 @@
             and environ.get(OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE) is not None
         ):
             credentials = _get_credentials(
-                credentials, OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE
+                credentials,
+                OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE,
+                OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY,
+                OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE,
             )
 
         environ_timeout = environ.get(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/src/opentelemetry/exporter/otlp/proto/grpc/version.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/src/opentelemetry/exporter/otlp/proto/grpc/version.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/src/opentelemetry/exporter/otlp/proto/grpc/version.py
     2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/src/opentelemetry/exporter/otlp/proto/grpc/version.py
     2020-02-02 01:00:00.000000000 +0100
@@ -12,4 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-__version__ = "1.25.0"
+__version__ = "1.27.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/tests/logs/test_otlp_logs_exporter.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/tests/logs/test_otlp_logs_exporter.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/tests/logs/test_otlp_logs_exporter.py
     2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/tests/logs/test_otlp_logs_exporter.py
     2020-02-02 01:00:00.000000000 +0100
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+# pylint: disable=too-many-lines
+
 import time
 from concurrent.futures import ThreadPoolExecutor
 from os.path import dirname
@@ -21,6 +23,7 @@
 from google.protobuf.duration_pb2 import (  # pylint: disable=no-name-in-module
     Duration,
 )
+from google.protobuf.json_format import MessageToDict
 from google.rpc.error_details_pb2 import RetryInfo
 from grpc import ChannelCredentials, Compression, StatusCode, server
 
@@ -52,6 +55,8 @@
 from opentelemetry.sdk._logs.export import LogExportResult
 from opentelemetry.sdk.environment_variables import (
     OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE,
+    OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE,
+    OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY,
     OTEL_EXPORTER_OTLP_LOGS_COMPRESSION,
     OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
     OTEL_EXPORTER_OTLP_LOGS_HEADERS,
@@ -77,7 +82,7 @@
                 (
                     "google.rpc.retryinfo-bin",
                     RetryInfo(
-                        retry_delay=Duration(seconds=4)
+                        retry_delay=Duration(nanos=int(1e7))
                     ).SerializeToString(),
                 ),
             )
@@ -167,6 +172,36 @@
                 "third_name", "third_version"
             ),
         )
+        self.log_data_4 = LogData(
+            log_record=LogRecord(
+                timestamp=int(time.time() * 1e9),
+                trace_id=0,
+                span_id=5213367945872657629,
+                trace_flags=TraceFlags(0x01),
+                severity_text="ERROR",
+                severity_number=SeverityNumber.WARN,
+                body="Invalid trace id check",
+                resource=SDKResource({"service": "myapp"}),
+            ),
+            instrumentation_scope=InstrumentationScope(
+                "fourth_name", "fourth_version"
+            ),
+        )
+        self.log_data_5 = LogData(
+            log_record=LogRecord(
+                timestamp=int(time.time() * 1e9),
+                trace_id=2604504634922341076776623263868986801,
+                span_id=0,
+                trace_flags=TraceFlags(0x01),
+                severity_text="ERROR",
+                severity_number=SeverityNumber.WARN,
+                body="Invalid span id check",
+                resource=SDKResource({"service": "myapp"}),
+            ),
+            instrumentation_scope=InstrumentationScope(
+                "fifth_name", "fifth_version"
+            ),
+        )
 
     def tearDown(self):
         self.server.stop(None)
@@ -179,8 +214,36 @@
         "os.environ",
         {
             OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317",
+            OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = VALUE=2",
+            OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10",
+            OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip",
+        },
+    )
+    @patch(
+        
"opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__"
+    )
+    def test_env_variables(self, mock_exporter_mixin):
+        OTLPLogExporter()
+
+        self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1)
+        _, kwargs = mock_exporter_mixin.call_args_list[0]
+        self.assertEqual(kwargs["endpoint"], "logs:4317")
+        self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = VALUE=2")
+        self.assertEqual(kwargs["timeout"], 10)
+        self.assertEqual(kwargs["compression"], Compression.Gzip)
+        self.assertIsNone(kwargs["credentials"])
+
+    # Create a new test method specifically for client certificates
+    @patch.dict(
+        "os.environ",
+        {
+            OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317",
             OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: THIS_DIR
             + "/../fixtures/test.cert",
+            OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE: THIS_DIR
+            + "/../fixtures/test-client-cert.pem",
+            OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY: THIS_DIR
+            + "/../fixtures/test-client-key.pem",
             OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = VALUE=2",
             OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10",
             OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip",
@@ -189,7 +252,36 @@
     @patch(
         
"opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__"
     )
-    def test_env_variables(self, mock_exporter_mixin):
+    def test_env_variables_with_client_certificates(self, mock_exporter_mixin):
+        OTLPLogExporter()
+
+        self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1)
+        _, kwargs = mock_exporter_mixin.call_args_list[0]
+        self.assertEqual(kwargs["endpoint"], "logs:4317")
+        self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = VALUE=2")
+        self.assertEqual(kwargs["timeout"], 10)
+        self.assertEqual(kwargs["compression"], Compression.Gzip)
+        self.assertIsNotNone(kwargs["credentials"])
+        self.assertIsInstance(kwargs["credentials"], ChannelCredentials)
+
+    @patch.dict(
+        "os.environ",
+        {
+            OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317",
+            OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: THIS_DIR
+            + "/../fixtures/test.cert",
+            OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = VALUE=2",
+            OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10",
+            OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip",
+        },
+    )
+    @patch(
+        
"opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__"
+    )
+    @patch("logging.Logger.error")
+    def test_env_variables_with_only_certificate(
+        self, mock_logger_error, mock_exporter_mixin
+    ):
         OTLPLogExporter()
 
         self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1)
@@ -201,6 +293,8 @@
         self.assertIsNotNone(kwargs["credentials"])
         self.assertIsInstance(kwargs["credentials"], ChannelCredentials)
 
+        mock_logger_error.assert_not_called()
+
     @patch(
         
"opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials"
     )
@@ -300,7 +394,7 @@
     @patch("opentelemetry.exporter.otlp.proto.grpc.exporter.sleep")
     def test_unavailable(self, mock_sleep, mock_expo):
 
-        mock_expo.configure_mock(**{"return_value": [1]})
+        mock_expo.configure_mock(**{"return_value": [0.01]})
 
         add_LogsServiceServicer_to_server(
             LogsServiceServicerUNAVAILABLE(), self.server
@@ -308,7 +402,7 @@
         self.assertEqual(
             self.exporter.export([self.log_data_1]), LogExportResult.FAILURE
         )
-        mock_sleep.assert_called_with(1)
+        mock_sleep.assert_called_with(0.01)
 
     @patch(
         
"opentelemetry.exporter.otlp.proto.grpc.exporter._create_exp_backoff_generator"
@@ -324,7 +418,7 @@
         self.assertEqual(
             self.exporter.export([self.log_data_1]), LogExportResult.FAILURE
         )
-        mock_sleep.assert_called_with(4)
+        mock_sleep.assert_called_with(0.01)
 
     def test_success(self):
         add_LogsServiceServicer_to_server(
@@ -342,6 +436,43 @@
             self.exporter.export([self.log_data_1]), LogExportResult.FAILURE
         )
 
+    def export_log_and_deserialize(self, log_data):
+        # pylint: disable=protected-access
+        translated_data = self.exporter._translate_data([log_data])
+        request_dict = MessageToDict(translated_data)
+        log_records = (
+            request_dict.get("resourceLogs")[0]
+            .get("scopeLogs")[0]
+            .get("logRecords")
+        )
+        return log_records
+
+    def test_exported_log_without_trace_id(self):
+        log_records = self.export_log_and_deserialize(self.log_data_4)
+        if log_records:
+            log_record = log_records[0]
+            self.assertIn("spanId", log_record)
+            self.assertNotIn(
+                "traceId",
+                log_record,
+                "traceId should not be present in the log record",
+            )
+        else:
+            self.fail("No log records found")
+
+    def test_exported_log_without_span_id(self):
+        log_records = self.export_log_and_deserialize(self.log_data_5)
+        if log_records:
+            log_record = log_records[0]
+            self.assertIn("traceId", log_record)
+            self.assertNotIn(
+                "spanId",
+                log_record,
+                "spanId should not be present in the log record",
+            )
+        else:
+            self.fail("No log records found")
+
     def test_translate_log_data(self):
 
         expected = ExportLogsServiceRequest(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/tests/performance/benchmarks/test_benchmark_trace_exporter.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/tests/performance/benchmarks/test_benchmark_trace_exporter.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/tests/performance/benchmarks/test_benchmark_trace_exporter.py
     2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/tests/performance/benchmarks/test_benchmark_trace_exporter.py
     1970-01-01 01:00:00.000000000 +0100
@@ -1,87 +0,0 @@
-# Copyright The OpenTelemetry Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from unittest.mock import patch
-
-from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
-    OTLPSpanExporter,
-)
-from opentelemetry.sdk.trace import TracerProvider, sampling
-from opentelemetry.sdk.trace.export import (
-    BatchSpanProcessor,
-    SimpleSpanProcessor,
-)
-
-
-def get_tracer_with_processor(span_processor_class):
-    span_processor = span_processor_class(OTLPSpanExporter())
-    tracer = TracerProvider(
-        active_span_processor=span_processor,
-        sampler=sampling.DEFAULT_ON,
-    ).get_tracer("pipeline_benchmark_tracer")
-    return tracer
-
-
-class MockTraceServiceStub:
-    def __init__(self, channel):
-        self.Export = lambda *args, **kwargs: None
-
-
-@patch(
-    
"opentelemetry.exporter.otlp.proto.grpc.trace_exporter.OTLPSpanExporter._stub",
-    new=MockTraceServiceStub,
-)
-def test_simple_span_processor(benchmark):
-    tracer = get_tracer_with_processor(SimpleSpanProcessor)
-
-    def create_spans_to_be_exported():
-        span = tracer.start_span(
-            "benchmarkedSpan",
-        )
-        for i in range(10):
-            span.set_attribute(
-                f"benchmarkAttribute_{i}",
-                f"benchmarkAttrValue_{i}",
-            )
-        span.end()
-
-    benchmark(create_spans_to_be_exported)
-
-
-@patch(
-    
"opentelemetry.exporter.otlp.proto.grpc.trace_exporter.OTLPSpanExporter._stub",
-    new=MockTraceServiceStub,
-)
-def test_batch_span_processor(benchmark):
-    """Runs benchmark tests using BatchSpanProcessor.
-
-    One particular call by pytest-benchmark will be much more expensive since
-    the batch export thread will activate and consume a lot of CPU to process
-    all the spans. For this reason, focus on the average measurement. Do not
-    focus on the min/max measurements which will be misleading.
-    """
-    tracer = get_tracer_with_processor(BatchSpanProcessor)
-
-    def create_spans_to_be_exported():
-        span = tracer.start_span(
-            "benchmarkedSpan",
-        )
-        for i in range(10):
-            span.set_attribute(
-                f"benchmarkAttribute_{i}",
-                f"benchmarkAttrValue_{i}",
-            )
-        span.end()
-
-    benchmark(create_spans_to_be_exported)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/tests/test_otlp_exporter_mixin.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/tests/test_otlp_exporter_mixin.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/tests/test_otlp_exporter_mixin.py
 2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/tests/test_otlp_exporter_mixin.py
 2020-02-02 01:00:00.000000000 +0100
@@ -13,8 +13,8 @@
 # limitations under the License.
 
 import threading
-import time
 from logging import WARNING
+from time import time_ns
 from types import MethodType
 from typing import Sequence
 from unittest import TestCase
@@ -163,7 +163,7 @@
         def trailing_metadata(self):
             return {
                 "google.rpc.retryinfo-bin": RetryInfo(
-                    retry_delay=Duration(seconds=1)
+                    retry_delay=Duration(nanos=int(1e7))
                 ).SerializeToString()
             }
 
@@ -196,9 +196,9 @@
             # pylint: disable=protected-access
             self.assertTrue(otlp_mock_exporter._export_lock.locked())
             # delay is 1 second while the default shutdown timeout is 30_000 
milliseconds
-            start_time = time.time()
+            start_time = time_ns()
             otlp_mock_exporter.shutdown()
-            now = time.time()
+            now = time_ns()
             self.assertGreaterEqual(now, (start_time + 30 / 1000))
             # pylint: disable=protected-access
             self.assertTrue(otlp_mock_exporter._shutdown)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/tests/test_otlp_metrics_exporter.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/tests/test_otlp_metrics_exporter.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/tests/test_otlp_metrics_exporter.py
       2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/tests/test_otlp_metrics_exporter.py
       2020-02-02 01:00:00.000000000 +0100
@@ -12,14 +12,16 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+# pylint: disable=too-many-lines
+
 import threading
-import time
 from concurrent.futures import ThreadPoolExecutor
 
 # pylint: disable=too-many-lines
 from logging import WARNING
 from os import environ
 from os.path import dirname
+from time import time_ns
 from typing import List
 from unittest import TestCase
 from unittest.mock import patch
@@ -45,6 +47,8 @@
 from opentelemetry.sdk.environment_variables import (
     OTEL_EXPORTER_OTLP_COMPRESSION,
     OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE,
+    OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE,
+    OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY,
     OTEL_EXPORTER_OTLP_METRICS_COMPRESSION,
     OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION,
     OTEL_EXPORTER_OTLP_METRICS_ENDPOINT,
@@ -97,7 +101,7 @@
                 (
                     "google.rpc.retryinfo-bin",
                     RetryInfo(
-                        retry_delay=Duration(seconds=4)
+                        retry_delay=Duration(nanos=int(1e7))
                     ).SerializeToString(),
                 ),
             )
@@ -221,8 +225,36 @@
         "os.environ",
         {
             OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "collector:4317",
+            OTEL_EXPORTER_OTLP_METRICS_HEADERS: " key1=value1,KEY2 = value=2",
+            OTEL_EXPORTER_OTLP_METRICS_TIMEOUT: "10",
+            OTEL_EXPORTER_OTLP_METRICS_COMPRESSION: "gzip",
+        },
+    )
+    @patch(
+        
"opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__"
+    )
+    def test_env_variables(self, mock_exporter_mixin):
+        OTLPMetricExporter()
+
+        self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1)
+        _, kwargs = mock_exporter_mixin.call_args_list[0]
+
+        self.assertEqual(kwargs["endpoint"], "collector:4317")
+        self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2")
+        self.assertEqual(kwargs["timeout"], 10)
+        self.assertEqual(kwargs["compression"], Compression.Gzip)
+        self.assertIsNone(kwargs["credentials"])
+
+    @patch.dict(
+        "os.environ",
+        {
+            OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "collector:4317",
             OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE: THIS_DIR
             + "/fixtures/test.cert",
+            OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE: THIS_DIR
+            + "/fixtures/test-client-cert.pem",
+            OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY: THIS_DIR
+            + "/fixtures/test-client-key.pem",
             OTEL_EXPORTER_OTLP_METRICS_HEADERS: " key1=value1,KEY2 = value=2",
             OTEL_EXPORTER_OTLP_METRICS_TIMEOUT: "10",
             OTEL_EXPORTER_OTLP_METRICS_COMPRESSION: "gzip",
@@ -231,7 +263,7 @@
     @patch(
         
"opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__"
     )
-    def test_env_variables(self, mock_exporter_mixin):
+    def test_env_variables_with_client_certificates(self, mock_exporter_mixin):
         OTLPMetricExporter()
 
         self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1)
@@ -244,6 +276,37 @@
         self.assertIsNotNone(kwargs["credentials"])
         self.assertIsInstance(kwargs["credentials"], ChannelCredentials)
 
+    @patch.dict(
+        "os.environ",
+        {
+            OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "collector:4317",
+            OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE: THIS_DIR
+            + "/fixtures/test.cert",
+            OTEL_EXPORTER_OTLP_METRICS_HEADERS: " key1=value1,KEY2 = value=2",
+            OTEL_EXPORTER_OTLP_METRICS_TIMEOUT: "10",
+            OTEL_EXPORTER_OTLP_METRICS_COMPRESSION: "gzip",
+        },
+    )
+    @patch(
+        
"opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__"
+    )
+    @patch("logging.Logger.error")
+    def test_env_variables_with_only_certificate(
+        self, mock_logger_error, mock_exporter_mixin
+    ):
+        OTLPMetricExporter()
+
+        self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1)
+        _, kwargs = mock_exporter_mixin.call_args_list[0]
+        self.assertEqual(kwargs["endpoint"], "collector:4317")
+        self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2")
+        self.assertEqual(kwargs["timeout"], 10)
+        self.assertEqual(kwargs["compression"], Compression.Gzip)
+        self.assertIsNotNone(kwargs["credentials"])
+        self.assertIsInstance(kwargs["credentials"], ChannelCredentials)
+
+        mock_logger_error.assert_not_called()
+
     @patch(
         
"opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials"
     )
@@ -423,7 +486,7 @@
     @patch("opentelemetry.exporter.otlp.proto.grpc.exporter.sleep")
     def test_unavailable(self, mock_sleep, mock_expo):
 
-        mock_expo.configure_mock(**{"return_value": [1]})
+        mock_expo.configure_mock(**{"return_value": [0.01]})
 
         add_MetricsServiceServicer_to_server(
             MetricsServiceServicerUNAVAILABLE(), self.server
@@ -432,7 +495,7 @@
             self.exporter.export(self.metrics["sum_int"]),
             MetricExportResult.FAILURE,
         )
-        mock_sleep.assert_called_with(1)
+        mock_sleep.assert_called_with(0.01)
 
     @patch(
         
"opentelemetry.exporter.otlp.proto.grpc.exporter._create_exp_backoff_generator"
@@ -449,7 +512,7 @@
             self.exporter.export(self.metrics["sum_int"]),
             MetricExportResult.FAILURE,
         )
-        mock_sleep.assert_called_with(4)
+        mock_sleep.assert_called_with(0.01)
 
     @patch(
         
"opentelemetry.exporter.otlp.proto.grpc.exporter._create_exp_backoff_generator"
@@ -802,9 +865,9 @@
             # pylint: disable=protected-access
             self.assertTrue(self.exporter._export_lock.locked())
             # delay is 4 seconds while the default shutdown timeout is 30_000 
milliseconds
-            start_time = time.time()
+            start_time = time_ns()
             self.exporter.shutdown()
-            now = time.time()
+            now = time_ns()
             self.assertGreaterEqual(now, (start_time + 30 / 1000))
             # pylint: disable=protected-access
             self.assertTrue(self.exporter._shutdown)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/tests/test_otlp_trace_exporter.py
 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/tests/test_otlp_trace_exporter.py
--- 
old/opentelemetry_exporter_otlp_proto_grpc-1.25.0/tests/test_otlp_trace_exporter.py
 2020-02-02 01:00:00.000000000 +0100
+++ 
new/opentelemetry_exporter_otlp_proto_grpc-1.27.0/tests/test_otlp_trace_exporter.py
 2020-02-02 01:00:00.000000000 +0100
@@ -12,11 +12,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+# pylint: disable=too-many-lines
+
 import os
 import threading
-import time
 from concurrent.futures import ThreadPoolExecutor
 from logging import WARNING
+from time import time_ns
 from unittest import TestCase
 from unittest.mock import Mock, PropertyMock, patch
 
@@ -56,6 +58,8 @@
 from opentelemetry.sdk.environment_variables import (
     OTEL_EXPORTER_OTLP_COMPRESSION,
     OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE,
+    OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE,
+    OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY,
     OTEL_EXPORTER_OTLP_TRACES_COMPRESSION,
     OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
     OTEL_EXPORTER_OTLP_TRACES_HEADERS,
@@ -91,7 +95,7 @@
                 (
                     "google.rpc.retryinfo-bin",
                     RetryInfo(
-                        retry_delay=Duration(seconds=4)
+                        retry_delay=Duration(nanos=int(1e7))
                     ).SerializeToString(),
                 ),
             )
@@ -149,7 +153,7 @@
         )
 
         type(event_mock).name = PropertyMock(return_value="a")
-
+        type(event_mock).dropped_attributes = PropertyMock(return_value=0)
         self.span = _Span(
             "a",
             context=Mock(
@@ -171,6 +175,7 @@
                         "attributes": BoundedAttributes(
                             attributes={"a": 1, "b": False}
                         ),
+                        "dropped_attributes": 0,
                         "kind": OTLPSpan.SpanKind.SPAN_KIND_INTERNAL,  # 
pylint: disable=no-member
                     }
                 )
@@ -230,8 +235,34 @@
         "os.environ",
         {
             OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "collector:4317",
+            OTEL_EXPORTER_OTLP_TRACES_HEADERS: " key1=value1,KEY2 = value=2",
+            OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: "10",
+            OTEL_EXPORTER_OTLP_TRACES_COMPRESSION: "gzip",
+        },
+    )
+    @patch(
+        
"opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__"
+    )
+    def test_env_variables(self, mock_exporter_mixin):
+        OTLPSpanExporter()
+        self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1)
+        _, kwargs = mock_exporter_mixin.call_args_list[0]
+        self.assertEqual(kwargs["endpoint"], "collector:4317")
+        self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2")
+        self.assertEqual(kwargs["timeout"], 10)
+        self.assertEqual(kwargs["compression"], Compression.Gzip)
+        self.assertIsNone(kwargs["credentials"])
+
+    @patch.dict(
+        "os.environ",
+        {
+            OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "collector:4317",
             OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE: THIS_DIR
             + "/fixtures/test.cert",
+            OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE: THIS_DIR
+            + "/fixtures/test-client-cert.pem",
+            OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY: THIS_DIR
+            + "/fixtures/test-client-key.pem",
             OTEL_EXPORTER_OTLP_TRACES_HEADERS: " key1=value1,KEY2 = value=2",
             OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: "10",
             OTEL_EXPORTER_OTLP_TRACES_COMPRESSION: "gzip",
@@ -240,12 +271,40 @@
     @patch(
         
"opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__"
     )
-    def test_env_variables(self, mock_exporter_mixin):
+    def test_env_variables_with_client_certificates(self, mock_exporter_mixin):
         OTLPSpanExporter()
 
         self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1)
         _, kwargs = mock_exporter_mixin.call_args_list[0]
+        self.assertEqual(kwargs["endpoint"], "collector:4317")
+        self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2")
+        self.assertEqual(kwargs["timeout"], 10)
+        self.assertEqual(kwargs["compression"], Compression.Gzip)
+        self.assertIsNotNone(kwargs["credentials"])
+        self.assertIsInstance(kwargs["credentials"], ChannelCredentials)
+
+    @patch.dict(
+        "os.environ",
+        {
+            OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "collector:4317",
+            OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE: THIS_DIR
+            + "/fixtures/test.cert",
+            OTEL_EXPORTER_OTLP_TRACES_HEADERS: " key1=value1,KEY2 = value=2",
+            OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: "10",
+            OTEL_EXPORTER_OTLP_TRACES_COMPRESSION: "gzip",
+        },
+    )
+    @patch(
+        
"opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__"
+    )
+    @patch("logging.Logger.error")
+    def test_env_variables_with_only_certificate(
+        self, mock_logger_error, mock_exporter_mixin
+    ):
+        OTLPSpanExporter()
 
+        self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1)
+        _, kwargs = mock_exporter_mixin.call_args_list[0]
         self.assertEqual(kwargs["endpoint"], "collector:4317")
         self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2")
         self.assertEqual(kwargs["timeout"], 10)
@@ -253,6 +312,8 @@
         self.assertIsNotNone(kwargs["credentials"])
         self.assertIsInstance(kwargs["credentials"], ChannelCredentials)
 
+        mock_logger_error.assert_not_called()
+
     @patch(
         
"opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials"
     )
@@ -466,14 +527,14 @@
     @patch("opentelemetry.exporter.otlp.proto.grpc.exporter.sleep")
     def test_unavailable(self, mock_sleep, mock_expo):
 
-        mock_expo.configure_mock(**{"return_value": [1]})
+        mock_expo.configure_mock(**{"return_value": [0.01]})
 
         add_TraceServiceServicer_to_server(
             TraceServiceServicerUNAVAILABLE(), self.server
         )
         result = self.exporter.export([self.span])
         self.assertEqual(result, SpanExportResult.FAILURE)
-        mock_sleep.assert_called_with(1)
+        mock_sleep.assert_called_with(0.01)
 
     @patch(
         
"opentelemetry.exporter.otlp.proto.grpc.exporter._create_exp_backoff_generator"
@@ -489,7 +550,7 @@
         self.assertEqual(
             self.exporter.export([self.span]), SpanExportResult.FAILURE
         )
-        mock_sleep.assert_called_with(4)
+        mock_sleep.assert_called_with(0.01)
 
     def test_success(self):
         add_TraceServiceServicer_to_server(
@@ -868,20 +929,6 @@
         self.assertTrue(isinstance(arr_value.values[1], AnyValue))
         self.assertEqual(arr_value.values[1].string_value, "123")
 
-        # Tracing specs currently does not support Mapping type attributes
-        # map_value = _translate_key_values(
-        #     "map_type", {"asd": "123", "def": "456"}
-        # )
-        # self.assertTrue(isinstance(map_value, KeyValue))
-        # self.assertEqual(map_value.key, "map_type")
-        # self.assertTrue(isinstance(map_value.value, AnyValue))
-        # self.assertTrue(isinstance(map_value.value.kvlist_value, 
KeyValueList))
-
-        # kvlist_value = map_value.value.kvlist_value
-        # self.assertTrue(isinstance(kvlist_value.values[0], KeyValue))
-        # self.assertEqual(kvlist_value.values[0].key, "asd")
-        # self.assertEqual(kvlist_value.values[0].value.string_value, "123")
-
     def test_dropped_values(self):
         span = get_span_with_dropped_attributes_events_links()
         # pylint:disable=protected-access
@@ -954,9 +1001,9 @@
             # pylint: disable=protected-access
             self.assertTrue(self.exporter._export_lock.locked())
             # delay is 4 seconds while the default shutdown timeout is 30_000 
milliseconds
-            start_time = time.time()
+            start_time = time_ns()
             self.exporter.shutdown()
-            now = time.time()
+            now = time_ns()
             self.assertGreaterEqual(now, (start_time + 30 / 1000))
             # pylint: disable=protected-access
             self.assertTrue(self.exporter._shutdown)

Reply via email to