Skip to content

ref: Remove context normalization #13420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion requirements-base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ redis>=2.10.3,<2.10.6
requests-oauthlib==0.3.3
requests[security]>=2.20.0,<2.21.0
selenium==3.141.0
semaphore>=0.4.35,<0.5.0
semaphore>=0.4.36,<0.5.0
sentry-sdk>=0.8.0
setproctitle>=1.1.7,<1.2.0
simplejson>=3.2.0,<3.9.0
Expand Down
9 changes: 0 additions & 9 deletions src/sentry/interfaces/contexts.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from django.utils.encoding import force_text

from sentry.interfaces.base import Interface, prune_empty_keys
from sentry.utils.contexts_normalization import normalize_os, normalize_runtime
from sentry.utils.safe import get_path, trim

__all__ = ('Contexts', )
Expand Down Expand Up @@ -121,10 +120,6 @@ class RuntimeContextType(ContextType):
'name': u'{name}',
}

def __init__(self, alias, data):
normalize_runtime(data)
super(RuntimeContextType, self).__init__(alias, data)


@contexttype
class BrowserContextType(ContextType):
Expand All @@ -146,10 +141,6 @@ class OsContextType(ContextType):
}
# build, rooted

def __init__(self, alias, data):
normalize_os(data)
super(OsContextType, self).__init__(alias, data)


@contexttype
class GpuContextType(ContextType):
Expand Down
76 changes: 0 additions & 76 deletions src/sentry/utils/contexts_normalization.py
Original file line number Diff line number Diff line change
@@ -1,84 +1,8 @@
from __future__ import absolute_import
import re

from ua_parser.user_agent_parser import Parse
from sentry.utils.safe import get_path, setdefault_path

# Environment.OSVersion (GetVersionEx) or RuntimeInformation.OSDescription, on Windows
_windows_re = re.compile('^(Microsoft )?Windows (NT )?(?P<version>\d+\.\d+\.\d+).*$')
# Format sent by Unreal Engine on macOS
_unreal_macos_re = re.compile(
'^Mac OS X (?P<version>\d+\.\d+\.\d+)( \((?P<build>[a-fA-F0-9]+)\))?$')
# Environment.OSVersion or RuntimeInformation.OSDescription (uname)
# on Mono and CoreCLR on macOS, iOS, Linux, etc
_uname_re = re.compile('^(?P<name>[a-zA-Z]+) (?P<version>\d+\.\d+\.\d+(\.[1-9]+)?).*$')
# Mono 5.4, .NET Core 2.0
_runtime_re = re.compile('^(?P<name>.*) (?P<version>\d+\.\d+(\.\d+){0,2}).*$')


def normalize_os(data):
raw_description = data.get('raw_description')
# If there's no name and version, attempts to infer from raw_description
if raw_description is not None \
and data.get('name') is None \
and data.get('version') is None:
r = _windows_re.search(raw_description)
if r:
data['name'] = 'Windows'
data['version'] = r.group('version')
else:
r = _unreal_macos_re.search(raw_description)
if r:
data['name'] = 'macOS'
data['version'] = r.group('version')
data['build'] = r.group('build')
else:
r = _uname_re.search(raw_description)
if r:
data['name'] = r.group('name')
data['kernel_version'] = r.group('version')


def normalize_runtime(data):
raw_description = data.get('raw_description')
# If there's no name and version, attempts to infer from raw_description
if raw_description is not None \
and data.get('name') is None \
and data.get('version') is None:
r = _runtime_re.search(raw_description)
if r:
data['name'] = r.group('name')
data['version'] = r.group('version')

# RuntimeInformation.FrameworkDescription doesn't return a very useful value.
# example: .NET Framework 4.7.3056.0
# Release key dug from registry and sent as #build
if (data.get('name') or "").startswith('.NET Framework'):
build = data.get('build')

if build is not None:
version_map = {
"378389": "4.5",
"378675": "4.5.1",
"378758": "4.5.1",
"379893": "4.5.2",
"393295": "4.6",
"393297": "4.6",
"394254": "4.6.1",
"394271": "4.6.1",
"394802": "4.6.2",
"394806": "4.6.2",
"460798": "4.7",
"460805": "4.7",
"461308": "4.7.1",
"461310": "4.7.1",
"461808": "4.7.2",
"461814": "4.7.2",
}
version = version_map.get(build, None)
if version is not None:
data['version'] = version


def _get_version(user_agent):
return '.'.join(
Expand Down
122 changes: 1 addition & 121 deletions tests/sentry/utils/test_contexts_normalization.py
Original file line number Diff line number Diff line change
@@ -1,128 +1,8 @@
from __future__ import absolute_import
from sentry.utils.contexts_normalization import (
normalize_os,
normalize_runtime,
normalize_user_agent
)
from sentry.utils.contexts_normalization import normalize_user_agent
from unittest import TestCase


class NormalizeRuntimeTests(TestCase):
def test_dotnet_framework_472(self):
data = {'raw_description': '.NET Framework 4.7.3056.0', 'build': "461814"}
normalize_runtime(data)
assert data['name'] == '.NET Framework'
assert data['version'] == '4.7.2'

def test_dotnet_framework_future_version(self):
# Unmapped build number doesn't override version
data = {'raw_description': '.NET Framework 200.0', 'build': "999999"}
normalize_runtime(data)
assert data['name'] == '.NET Framework'
assert data['version'] == '200.0'

def test_dotnet_native(self):
data = {'raw_description': '.NET Native 2.0'}
normalize_runtime(data)
assert data['name'] == '.NET Native'
assert data['version'] == '2.0'

def test_dotnet_core(self):
data = {'raw_description': '.NET Core 2.0'}
normalize_runtime(data)
assert data['name'] == '.NET Core'
assert data['version'] == '2.0'


class NormalizeOsTests(TestCase):
# Environment.OSVersion on Windows 7 (CoreCLR 1.0+, .NET Framework 1.1+, Mono 1+)
def test_windows_7_or_server_2008(self):
data = {'raw_description': 'Microsoft Windows NT 6.1.7601 Service Pack 1'}
normalize_os(data)
assert data['name'] == 'Windows'
assert data['version'] == '6.1.7601'

# Environment.OSVersion on Windows 10 (CoreCLR 1.0+, .NET Framework 1.1+, Mono 1+)
# *or later, due to GetVersionEx deprecated on Windows 8.1
# It's a potentially really misleading API on newer platforms
# Only used if RuntimeInformation.OSDescription is not available (old runtimes)
def test_windows_8_or_server_2012_or_later(self):
data = {'raw_description': 'Microsoft Windows NT 6.2.9200.0'}
normalize_os(data)
assert data['name'] == 'Windows'
assert data['version'] == '6.2.9200'

# RuntimeInformation.OSDescription on Windows 10 (CoreCLR 2.0+, .NET
# Framework 4.7.1+, Mono 5.4+)
def test_windows_10(self):
data = {'raw_description': 'Microsoft Windows 10.0.16299'}
normalize_os(data)
assert data['name'] == 'Windows'
assert data['version'] == '10.0.16299'

# Environment.OSVersion on macOS (CoreCLR 1.0+, Mono 1+)
def test_macos(self):
data = {'raw_description': 'Unix 17.5.0.0'}
normalize_os(data)
assert data['name'] == 'Unix'
assert data['kernel_version'] == '17.5.0'

# Environment.OSVersion on CentOS 7 (CoreCLR 1.0+, Mono 1+)
def test_centos_os_version(self):
data = {'raw_description': 'Unix 3.10.0.693'}
normalize_os(data)
assert data['name'] == 'Unix'
assert data['kernel_version'] == '3.10.0.693'

# RuntimeInformation.OSDescription on CentOS 7 (CoreCLR 2.0+, Mono 5.4+)
def test_centos_runtime_info(self):
data = {'raw_description': 'Linux 3.10.0-693.21.1.el7.x86_64 #1 SMP Wed Mar 7 19:03:37 UTC 2018'}
normalize_os(data)
assert data['name'] == 'Linux'
assert data['kernel_version'] == '3.10.0'

# RuntimeInformation.OSDescription on macOS (CoreCLR 2.0+, Mono 5.4+)
def test_darwin(self):
data = {'raw_description': 'Darwin 17.5.0 Darwin Kernel Version 17.5.0: Mon Mar 5 22:24:32 PST 2018; root:xnu-4570.51.1~1/RELEASE_X86_64'}
normalize_os(data)
assert data['name'] == 'Darwin'
assert data['kernel_version'] == '17.5.0'

# RuntimeInformation.OSDescription on Windows Subsystem for Linux (Ubuntu)
# (CoreCLR 2.0+, Mono 5.4+)
def test_wsl_ubuntu(self):
data = {'raw_description': 'Linux 4.4.0-43-Microsoft #1-Microsoft Wed Dec 31 14:42:53 PST 2014'}
normalize_os(data)
assert data['name'] == 'Linux'
assert data['kernel_version'] == '4.4.0'

def test_name_not_overwritten(self):
data = {'name': 'Properly defined name', 'raw_description': 'Linux 4.4.0'}
normalize_os(data)
assert data['name'] == 'Properly defined name'

def test_version_not_overwritten(self):
data = {'version': 'Properly defined version', 'raw_description': 'Linux 4.4.0'}
normalize_os(data)
assert data['version'] == 'Properly defined version'

# As reported by Unreal Engine crashes from macOS
def test_macos_unreal(self):
data = {'raw_description': 'Mac OS X 10.14.2 (18C54)'}
normalize_os(data)
assert data['name'] == 'macOS'
assert data['version'] == '10.14.2'
assert data['build'] == '18C54'

def test_no_name(self):
data = {}
normalize_os(data)
assert 'name' not in data
assert 'version' not in data
assert 'kernel_version' not in data
assert 'raw_description' not in data


class NormalizeUserAgentTests(TestCase):
def setUp(self):
self.data = {'request':
Expand Down