feat: sentry for arm
Some checks failed
Lock closed issues/PRs / lock (push) Has been cancelled
Test / Sentry self-hosted end-to-end tests (push) Has been cancelled
Test / unit tests (push) Has been cancelled
Test / Sentry upgrade test (push) Has been cancelled
Test / integration test v2.19.0 - customizations disabled (push) Has been cancelled
Test / integration test v2.19.0 - customizations enabled (push) Has been cancelled
Test / integration test v2.26.0 - customizations disabled (push) Has been cancelled
Test / integration test v2.26.0 - customizations enabled (push) Has been cancelled
Some checks failed
Lock closed issues/PRs / lock (push) Has been cancelled
Test / Sentry self-hosted end-to-end tests (push) Has been cancelled
Test / unit tests (push) Has been cancelled
Test / Sentry upgrade test (push) Has been cancelled
Test / integration test v2.19.0 - customizations disabled (push) Has been cancelled
Test / integration test v2.19.0 - customizations enabled (push) Has been cancelled
Test / integration test v2.26.0 - customizations disabled (push) Has been cancelled
Test / integration test v2.26.0 - customizations enabled (push) Has been cancelled
Signed-off-by: 小草林(田梓萱) <xcl@xuegao-tzx.top>
This commit is contained in:
82
_integration-test/conftest.py
Normal file
82
_integration-test/conftest.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import os
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
SENTRY_CONFIG_PY = "sentry/sentry.conf.py"
|
||||
SENTRY_TEST_HOST = os.getenv("SENTRY_TEST_HOST", "http://localhost:96")
|
||||
TEST_USER = "test@example.com"
|
||||
TEST_PASS = "test123TEST"
|
||||
TIMEOUT_SECONDS = 60
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption("--customizations", default="disabled")
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def configure_self_hosted_environment(request):
|
||||
subprocess.run(
|
||||
["docker", "compose", "--ansi", "never", "up", "-d"],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
for i in range(TIMEOUT_SECONDS):
|
||||
try:
|
||||
response = httpx.get(SENTRY_TEST_HOST, follow_redirects=True)
|
||||
except httpx.RequestError:
|
||||
time.sleep(1)
|
||||
else:
|
||||
if response.status_code == 200:
|
||||
break
|
||||
else:
|
||||
raise AssertionError("timeout waiting for self-hosted to come up")
|
||||
|
||||
if request.config.getoption("--customizations") == "enabled":
|
||||
os.environ["TEST_CUSTOMIZATIONS"] = "enabled"
|
||||
script_content = """\
|
||||
#!/bin/bash
|
||||
touch /created-by-enhance-image
|
||||
apt-get update
|
||||
apt-get install -y gcc libsasl2-dev python-dev-is-python3 libldap2-dev libssl-dev
|
||||
"""
|
||||
|
||||
with open("sentry/enhance-image.sh", "w") as script_file:
|
||||
script_file.write(script_content)
|
||||
# Set executable permissions for the shell script
|
||||
os.chmod("sentry/enhance-image.sh", 0o755)
|
||||
|
||||
# Write content to the requirements.txt file
|
||||
with open("sentry/requirements.txt", "w") as req_file:
|
||||
req_file.write("python-ldap\n")
|
||||
os.environ["MINIMIZE_DOWNTIME"] = "1"
|
||||
subprocess.run(["./install.sh"], check=True, capture_output=True)
|
||||
# Create test user
|
||||
subprocess.run(
|
||||
[
|
||||
"docker",
|
||||
"compose",
|
||||
"exec",
|
||||
"-T",
|
||||
"web",
|
||||
"sentry",
|
||||
"createuser",
|
||||
"--force-update",
|
||||
"--superuser",
|
||||
"--email",
|
||||
TEST_USER,
|
||||
"--password",
|
||||
TEST_PASS,
|
||||
"--no-input",
|
||||
],
|
||||
check=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def setup_backup_restore_env_variables():
|
||||
os.environ["SENTRY_DOCKER_IO_DIR"] = os.path.join(os.getcwd(), "sentry")
|
||||
os.environ["SKIP_USER_CREATION"] = "1"
|
16
_integration-test/custom-ca-roots/custom-ca-roots-test.py
Normal file
16
_integration-test/custom-ca-roots/custom-ca-roots-test.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import unittest
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
class CustomCATests(unittest.TestCase):
|
||||
def test_valid_self_signed(self):
|
||||
self.assertEqual(requests.get("https://self.test").text, "ok")
|
||||
|
||||
def test_invalid_self_signed(self):
|
||||
with self.assertRaises(requests.exceptions.SSLError):
|
||||
requests.get("https://fail.test")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
12
_integration-test/custom-ca-roots/docker-compose.test.yml
Normal file
12
_integration-test/custom-ca-roots/docker-compose.test.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
version: '3.4'
|
||||
services:
|
||||
fixture-custom-ca-roots:
|
||||
image: nginx:1.21.0-alpine
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./_integration-test/custom-ca-roots/nginx:/etc/nginx:ro
|
||||
networks:
|
||||
default:
|
||||
aliases:
|
||||
- self.test
|
||||
- fail.test
|
5
_integration-test/fixtures/envelope-with-profile
Normal file
5
_integration-test/fixtures/envelope-with-profile
Normal file
@@ -0,0 +1,5 @@
|
||||
{"event_id":"66578634d48d433db0ad52882d1efe5b","sent_at":"2023-05-17T14:54:31.057Z","sdk":{"name":"sentry.javascript.node","version":"7.46.0"},"trace":{"environment":"production","transaction":"fib: sourcemaps here","public_key":"05ab86aebbe14a24bcab62caa839cf27","trace_id":"33321bfbd5304bcc9663d1b53b08f84e","sample_rate":"1"}}
|
||||
{"type":"transaction"}
|
||||
{"contexts":{"profile":{"profile_id":"e73aaf1f29b24812be60132f32d09f92"},"trace":{"op":"test","span_id":"b38f2b24537c3858","trace_id":"33321bfbd5304bcc9663d1b53b08f84e"},"runtime":{"name":"node","version":"v16.16.0"},"app":{"app_start_time":"2023-05-17T14:54:27.678Z","app_memory":57966592},"os":{"kernel_version":"22.3.0","name":"macOS","version":"13.2","build":"22D49"},"device":{"boot_time":"2023-05-12T15:08:41.047Z","arch":"arm64","memory_size":34359738368,"free_memory":6861651968,"processor_count":10,"cpu_description":"Apple M1 Pro","processor_frequency":24},"culture":{"locale":"en-US","timezone":"America/New_York"}},"spans":[],"start_timestamp":1684335267.744,"tags":{},"timestamp":1684335271.033,"transaction":"fib: sourcemaps here","type":"transaction","transaction_info":{"source":"custom"},"platform":"node","server_name":"TK6G745PW1.local","event_id":"66578634d48d433db0ad52882d1efe5b","environment":"production","sdk":{"integrations":["InboundFilters","FunctionToString","Console","Http","OnUncaughtException","OnUnhandledRejection","ContextLines","LocalVariables","Context","Modules","RequestData","LinkedErrors","ProfilingIntegration"],"name":"sentry.javascript.node","version":"7.46.0","packages":[{"name":"npm:@sentry/node","version":"7.46.0"}]},"debug_meta":{"images":[]},"modules":{}}
|
||||
{"type":"profile"}
|
||||
{"event_id":"e73aaf1f29b24812be60132f32d09f92","timestamp":"2023-05-17T14:54:27.744Z","platform":"node","version":"1","release":"","environment":"production","runtime":{"name":"node","version":"16.16.0"},"os":{"name":"darwin","version":"22.3.0","build_number":"Darwin Kernel Version 22.3.0: Thu Jan 5 20:48:54 PST 2023; root:xnu-8792.81.2~2/RELEASE_ARM64_T6000"},"device":{"locale":"en_US.UTF-8","model":"arm64","manufacturer":"Darwin","architecture":"arm64","is_emulator":false},"debug_meta":{"images":[]},"profile":{"samples":[{"stack_id":0,"thread_id":"0","elapsed_since_start_ns":125000},{"stack_id":0,"thread_id":"0","elapsed_since_start_ns":13958000}],"frames":[{"lineno":14129,"colno":17,"function":"startProfiling","abs_path":"/Users/jonasbadalic/code/node-profiler/lib/index.js"}],"stacks":[[0]],"thread_metadata":{"0":{"name":"main"}}},"transaction":{"name":"fib: sourcemaps here","id":"66578634d48d433db0ad52882d1efe5b","trace_id":"33321bfbd5304bcc9663d1b53b08f84e","active_thread_id":"0"}}
|
3
_integration-test/fixtures/envelope-with-transaction
Normal file
3
_integration-test/fixtures/envelope-with-transaction
Normal file
@@ -0,0 +1,3 @@
|
||||
{"event_id":"66578634d48d433db0ad52882d1efe5b","sent_at":"2023-05-17T14:54:31.057Z","sdk":{"name":"sentry.javascript.node","version":"7.46.0"},"trace":{"environment":"production","transaction":"fib: sourcemaps here","public_key":"05ab86aebbe14a24bcab62caa839cf27","trace_id":"33321bfbd5304bcc9663d1b53b08f84e","sample_rate":"1"}}
|
||||
{"type":"transaction"}
|
||||
{"contexts":{"trace":{"op":"test","span_id":"b38f2b24537c3858","trace_id":"33321bfbd5304bcc9663d1b53b08f84e"},"runtime":{"name":"node","version":"v16.16.0"},"app":{"app_start_time":"2023-05-17T14:54:27.678Z","app_memory":57966592},"os":{"kernel_version":"22.3.0","name":"macOS","version":"13.2","build":"22D49"},"device":{"boot_time":"2023-05-12T15:08:41.047Z","arch":"arm64","memory_size":34359738368,"free_memory":6861651968,"processor_count":10,"cpu_description":"Apple M1 Pro","processor_frequency":24},"culture":{"locale":"en-US","timezone":"America/New_York"}},"spans":[],"start_timestamp":1684335267.744,"tags":{},"timestamp":1684335271.033,"transaction":"fib: sourcemaps here","type":"transaction","transaction_info":{"source":"custom"},"platform":"node","server_name":"TK6G745PW1.local","event_id":"66578634d48d433db0ad52882d1efe5b","environment":"production","sdk":{"integrations":["InboundFilters","FunctionToString","Console","Http","OnUncaughtException","OnUnhandledRejection","ContextLines","LocalVariables","Context","Modules","RequestData","LinkedErrors","ProfilingIntegration"],"name":"sentry.javascript.node","version":"7.46.0","packages":[{"name":"npm:@sentry/node","version":"7.46.0"}]},"debug_meta":{"images":[]},"modules":{}}
|
73
_integration-test/test_backup.py
Normal file
73
_integration-test/test_backup.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
def test_sentry_admin(setup_backup_restore_env_variables):
|
||||
sentry_admin_sh = os.path.join(os.getcwd(), "sentry-admin.sh")
|
||||
output = subprocess.run(
|
||||
[sentry_admin_sh, "--help"], check=True, capture_output=True, encoding="utf8"
|
||||
).stdout
|
||||
assert "Usage: ./sentry-admin.sh" in output
|
||||
assert "SENTRY_DOCKER_IO_DIR" in output
|
||||
|
||||
output = subprocess.run(
|
||||
[sentry_admin_sh, "permissions", "--help"],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
encoding="utf8",
|
||||
).stdout
|
||||
assert "Usage: ./sentry-admin.sh permissions" in output
|
||||
|
||||
|
||||
def test_backup(setup_backup_restore_env_variables):
|
||||
# Docker was giving me permissioning issues when trying to create this file and write to it even after giving read + write access
|
||||
# to group and owner. Instead, try creating the empty file and then give everyone write access to the backup file
|
||||
file_path = os.path.join(os.getcwd(), "sentry", "backup.json")
|
||||
sentry_admin_sh = os.path.join(os.getcwd(), "sentry-admin.sh")
|
||||
open(file_path, "a", encoding="utf8").close()
|
||||
os.chmod(file_path, 0o666)
|
||||
assert os.path.getsize(file_path) == 0
|
||||
subprocess.run(
|
||||
[
|
||||
sentry_admin_sh,
|
||||
"export",
|
||||
"global",
|
||||
"/sentry-admin/backup.json",
|
||||
"--no-prompt",
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
assert os.path.getsize(file_path) > 0
|
||||
|
||||
|
||||
def test_import(setup_backup_restore_env_variables):
|
||||
# Bring postgres down and recreate the docker volume
|
||||
subprocess.run(
|
||||
["docker", "compose", "--ansi", "never", "stop", "postgres"], check=True
|
||||
)
|
||||
subprocess.run(
|
||||
["docker", "compose", "--ansi", "never", "rm", "-f", "-v", "postgres"],
|
||||
check=True,
|
||||
)
|
||||
subprocess.run(["docker", "volume", "rm", "sentry-postgres"], check=True)
|
||||
subprocess.run(["docker", "volume", "create", "--name=sentry-postgres"], check=True)
|
||||
subprocess.run(
|
||||
["docker", "compose", "--ansi", "never", "run", "web", "upgrade", "--noinput"],
|
||||
check=True,
|
||||
)
|
||||
subprocess.run(
|
||||
["docker", "compose", "--ansi", "never", "up", "-d"],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
sentry_admin_sh = os.path.join(os.getcwd(), "sentry-admin.sh")
|
||||
subprocess.run(
|
||||
[
|
||||
sentry_admin_sh,
|
||||
"import",
|
||||
"global",
|
||||
"/sentry-admin/backup.json",
|
||||
"--no-prompt",
|
||||
],
|
||||
check=True,
|
||||
)
|
446
_integration-test/test_run.py
Normal file
446
_integration-test/test_run.py
Normal file
@@ -0,0 +1,446 @@
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
from functools import lru_cache
|
||||
from typing import Callable
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
import sentry_sdk
|
||||
from bs4 import BeautifulSoup
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import hashes, serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
from cryptography.x509.oid import NameOID
|
||||
|
||||
SENTRY_CONFIG_PY = "sentry/sentry.conf.py"
|
||||
SENTRY_TEST_HOST = os.getenv("SENTRY_TEST_HOST", "http://localhost:96")
|
||||
TEST_USER = "test@example.com"
|
||||
TEST_PASS = "test123TEST"
|
||||
TIMEOUT_SECONDS = 60
|
||||
|
||||
|
||||
def poll_for_response(
|
||||
request: str, client: httpx.Client, validator: Callable = None
|
||||
) -> httpx.Response:
|
||||
for i in range(TIMEOUT_SECONDS):
|
||||
response = client.get(
|
||||
request, follow_redirects=True, headers={"Referer": SENTRY_TEST_HOST}
|
||||
)
|
||||
if response.status_code == 200:
|
||||
if validator is None or validator(response.text):
|
||||
break
|
||||
time.sleep(1)
|
||||
else:
|
||||
raise AssertionError(
|
||||
"timeout waiting for response status code 200 or valid data"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@lru_cache
|
||||
def get_sentry_dsn(client: httpx.Client) -> str:
|
||||
response = poll_for_response(
|
||||
f"{SENTRY_TEST_HOST}/api/0/projects/sentry/internal/keys/",
|
||||
client,
|
||||
lambda x: len(json.loads(x)[0]["dsn"]["public"]) > 0,
|
||||
)
|
||||
sentry_dsn = json.loads(response.text)[0]["dsn"]["public"]
|
||||
return sentry_dsn
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def client_login():
|
||||
client = httpx.Client()
|
||||
response = client.get(SENTRY_TEST_HOST, follow_redirects=True)
|
||||
parser = BeautifulSoup(response.text, "html.parser")
|
||||
login_csrf_token = parser.find("input", {"name": "csrfmiddlewaretoken"})["value"]
|
||||
login_response = client.post(
|
||||
f"{SENTRY_TEST_HOST}/auth/login/sentry/",
|
||||
follow_redirects=True,
|
||||
data={
|
||||
"op": "login",
|
||||
"username": TEST_USER,
|
||||
"password": TEST_PASS,
|
||||
"csrfmiddlewaretoken": login_csrf_token,
|
||||
},
|
||||
headers={"Referer": f"{SENTRY_TEST_HOST}/auth/login/sentry/"},
|
||||
)
|
||||
assert login_response.status_code == 200
|
||||
yield (client, login_response)
|
||||
|
||||
|
||||
def test_initial_redirect():
|
||||
initial_auth_redirect = httpx.get(SENTRY_TEST_HOST, follow_redirects=True)
|
||||
assert initial_auth_redirect.url == f"{SENTRY_TEST_HOST}/auth/login/sentry/"
|
||||
|
||||
|
||||
def test_login(client_login):
|
||||
client, login_response = client_login
|
||||
parser = BeautifulSoup(login_response.text, "html.parser")
|
||||
script_tag = parser.find(
|
||||
"script", string=lambda x: x and "window.__initialData" in x
|
||||
)
|
||||
assert script_tag is not None
|
||||
json_data = json.loads(script_tag.text.split("=", 1)[1].strip().rstrip(";"))
|
||||
assert json_data["isAuthenticated"] is True
|
||||
assert json_data["user"]["username"] == "test@example.com"
|
||||
assert json_data["user"]["isSuperuser"] is True
|
||||
assert login_response.cookies["sc"] is not None
|
||||
# Set up initial/required settings (InstallWizard request)
|
||||
client.headers.update({"X-CSRFToken": login_response.cookies["sc"]})
|
||||
response = client.put(
|
||||
f"{SENTRY_TEST_HOST}/api/0/internal/options/?query=is:required",
|
||||
follow_redirects=True,
|
||||
headers={"Referer": SENTRY_TEST_HOST},
|
||||
data={
|
||||
"mail.use-tls": False,
|
||||
"mail.username": "",
|
||||
"mail.port": 25,
|
||||
"system.admin-email": "test@example.com",
|
||||
"mail.password": "",
|
||||
"system.url-prefix": SENTRY_TEST_HOST,
|
||||
"auth.allow-registration": False,
|
||||
"beacon.anonymous": True,
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_receive_event(client_login):
|
||||
event_id = None
|
||||
client, _ = client_login
|
||||
with sentry_sdk.init(dsn=get_sentry_dsn(client)):
|
||||
event_id = sentry_sdk.capture_exception(Exception("a failure"))
|
||||
assert event_id is not None
|
||||
response = poll_for_response(
|
||||
f"{SENTRY_TEST_HOST}/api/0/projects/sentry/internal/events/{event_id}/", client
|
||||
)
|
||||
response_json = json.loads(response.text)
|
||||
assert response_json["eventID"] == event_id
|
||||
assert response_json["metadata"]["value"] == "a failure"
|
||||
|
||||
|
||||
def test_cleanup_crons_running():
|
||||
docker_services = subprocess.check_output(
|
||||
[
|
||||
"docker",
|
||||
"compose",
|
||||
"--ansi",
|
||||
"never",
|
||||
"ps",
|
||||
"-a",
|
||||
],
|
||||
text=True,
|
||||
)
|
||||
pattern = re.compile(
|
||||
r"(\-cleanup\s+running)|(\-cleanup[_-].+\s+Up\s+)", re.MULTILINE
|
||||
)
|
||||
cleanup_crons = pattern.findall(docker_services)
|
||||
assert len(cleanup_crons) > 0
|
||||
|
||||
|
||||
def test_custom_certificate_authorities():
|
||||
# Set environment variable
|
||||
os.environ["COMPOSE_FILE"] = (
|
||||
"docker-compose.yml:_integration-test/custom-ca-roots/docker-compose.test.yml"
|
||||
)
|
||||
|
||||
test_nginx_conf_path = "_integration-test/custom-ca-roots/nginx"
|
||||
custom_certs_path = "certificates"
|
||||
|
||||
# Generate tightly constrained CA
|
||||
ca_key = rsa.generate_private_key(
|
||||
public_exponent=65537, key_size=2048, backend=default_backend()
|
||||
)
|
||||
|
||||
ca_name = x509.Name(
|
||||
[x509.NameAttribute(NameOID.COMMON_NAME, "TEST CA *DO NOT TRUST*")]
|
||||
)
|
||||
|
||||
ca_cert = (
|
||||
x509.CertificateBuilder()
|
||||
.subject_name(ca_name)
|
||||
.issuer_name(ca_name)
|
||||
.public_key(ca_key.public_key())
|
||||
.serial_number(x509.random_serial_number())
|
||||
.not_valid_before(datetime.datetime.utcnow())
|
||||
.not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=1))
|
||||
.add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True)
|
||||
.add_extension(
|
||||
x509.KeyUsage(
|
||||
digital_signature=False,
|
||||
key_encipherment=False,
|
||||
content_commitment=False,
|
||||
data_encipherment=False,
|
||||
key_agreement=False,
|
||||
key_cert_sign=True,
|
||||
crl_sign=True,
|
||||
encipher_only=False,
|
||||
decipher_only=False,
|
||||
),
|
||||
critical=True,
|
||||
)
|
||||
.add_extension(
|
||||
x509.NameConstraints([x509.DNSName("self.test")], None), critical=True
|
||||
)
|
||||
.sign(private_key=ca_key, algorithm=hashes.SHA256(), backend=default_backend())
|
||||
)
|
||||
|
||||
ca_key_path = f"{test_nginx_conf_path}/ca.key"
|
||||
ca_crt_path = f"{test_nginx_conf_path}/ca.crt"
|
||||
|
||||
with open(ca_key_path, "wb") as key_file:
|
||||
key_file.write(
|
||||
ca_key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
encryption_algorithm=serialization.NoEncryption(),
|
||||
)
|
||||
)
|
||||
|
||||
with open(ca_crt_path, "wb") as cert_file:
|
||||
cert_file.write(ca_cert.public_bytes(serialization.Encoding.PEM))
|
||||
|
||||
# Create custom certs path and copy ca.crt
|
||||
os.makedirs(custom_certs_path, exist_ok=True)
|
||||
shutil.copyfile(ca_crt_path, f"{custom_certs_path}/test-custom-ca-roots.crt")
|
||||
# Generate server key and certificate
|
||||
|
||||
self_test_key_path = os.path.join(test_nginx_conf_path, "self.test.key")
|
||||
self_test_csr_path = os.path.join(test_nginx_conf_path, "self.test.csr")
|
||||
self_test_cert_path = os.path.join(test_nginx_conf_path, "self.test.crt")
|
||||
|
||||
self_test_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
||||
|
||||
self_test_req = (
|
||||
x509.CertificateSigningRequestBuilder()
|
||||
.subject_name(
|
||||
x509.Name(
|
||||
[
|
||||
x509.NameAttribute(
|
||||
NameOID.COMMON_NAME, "Self Signed with CA Test Server"
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
.add_extension(
|
||||
x509.SubjectAlternativeName([x509.DNSName("self.test")]), critical=False
|
||||
)
|
||||
.sign(self_test_key, hashes.SHA256())
|
||||
)
|
||||
|
||||
self_test_cert = (
|
||||
x509.CertificateBuilder()
|
||||
.subject_name(
|
||||
x509.Name(
|
||||
[
|
||||
x509.NameAttribute(
|
||||
NameOID.COMMON_NAME, "Self Signed with CA Test Server"
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
.issuer_name(ca_cert.issuer)
|
||||
.serial_number(x509.random_serial_number())
|
||||
.not_valid_before(datetime.datetime.utcnow())
|
||||
.not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=1))
|
||||
.public_key(self_test_req.public_key())
|
||||
.add_extension(
|
||||
x509.SubjectAlternativeName([x509.DNSName("self.test")]), critical=False
|
||||
)
|
||||
.sign(private_key=ca_key, algorithm=hashes.SHA256())
|
||||
)
|
||||
|
||||
# Save server key, CSR, and certificate
|
||||
with open(self_test_key_path, "wb") as key_file:
|
||||
key_file.write(
|
||||
self_test_key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
encryption_algorithm=serialization.NoEncryption(),
|
||||
)
|
||||
)
|
||||
with open(self_test_csr_path, "wb") as csr_file:
|
||||
csr_file.write(self_test_req.public_bytes(serialization.Encoding.PEM))
|
||||
with open(self_test_cert_path, "wb") as cert_file:
|
||||
cert_file.write(self_test_cert.public_bytes(serialization.Encoding.PEM))
|
||||
|
||||
# Generate server key and certificate for fake.test
|
||||
|
||||
fake_test_key_path = os.path.join(test_nginx_conf_path, "fake.test.key")
|
||||
fake_test_cert_path = os.path.join(test_nginx_conf_path, "fake.test.crt")
|
||||
|
||||
fake_test_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
||||
|
||||
fake_test_cert = (
|
||||
x509.CertificateBuilder()
|
||||
.subject_name(
|
||||
x509.Name(
|
||||
[x509.NameAttribute(NameOID.COMMON_NAME, "Self Signed Test Server")]
|
||||
)
|
||||
)
|
||||
.issuer_name(
|
||||
x509.Name(
|
||||
[x509.NameAttribute(NameOID.COMMON_NAME, "Self Signed Test Server")]
|
||||
)
|
||||
)
|
||||
.serial_number(x509.random_serial_number())
|
||||
.not_valid_before(datetime.datetime.utcnow())
|
||||
.not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=1))
|
||||
.public_key(fake_test_key.public_key())
|
||||
.add_extension(
|
||||
x509.SubjectAlternativeName([x509.DNSName("fake.test")]), critical=False
|
||||
)
|
||||
.sign(private_key=fake_test_key, algorithm=hashes.SHA256())
|
||||
)
|
||||
|
||||
# Save server key and certificate for fake.test
|
||||
with open(fake_test_key_path, "wb") as key_file:
|
||||
key_file.write(
|
||||
fake_test_key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
encryption_algorithm=serialization.NoEncryption(),
|
||||
)
|
||||
)
|
||||
# Our asserts for this test case must be executed within the web container, so we are copying a python test script into the mounted sentry directory
|
||||
with open(fake_test_cert_path, "wb") as cert_file:
|
||||
cert_file.write(fake_test_cert.public_bytes(serialization.Encoding.PEM))
|
||||
shutil.copyfile(
|
||||
"_integration-test/custom-ca-roots/custom-ca-roots-test.py",
|
||||
"sentry/test-custom-ca-roots.py",
|
||||
)
|
||||
|
||||
subprocess.run(
|
||||
["docker", "compose", "--ansi", "never", "up", "-d", "fixture-custom-ca-roots"],
|
||||
check=True,
|
||||
)
|
||||
subprocess.run(
|
||||
[
|
||||
"docker",
|
||||
"compose",
|
||||
"--ansi",
|
||||
"never",
|
||||
"run",
|
||||
"--no-deps",
|
||||
"web",
|
||||
"python3",
|
||||
"/etc/sentry/test-custom-ca-roots.py",
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
subprocess.run(
|
||||
[
|
||||
"docker",
|
||||
"compose",
|
||||
"--ansi",
|
||||
"never",
|
||||
"rm",
|
||||
"-s",
|
||||
"-f",
|
||||
"-v",
|
||||
"fixture-custom-ca-roots",
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
|
||||
# Remove files
|
||||
os.remove(f"{custom_certs_path}/test-custom-ca-roots.crt")
|
||||
os.remove("sentry/test-custom-ca-roots.py")
|
||||
|
||||
# Unset environment variable
|
||||
if "COMPOSE_FILE" in os.environ:
|
||||
del os.environ["COMPOSE_FILE"]
|
||||
|
||||
|
||||
def test_receive_transaction_events(client_login):
|
||||
client, _ = client_login
|
||||
with sentry_sdk.init(
|
||||
dsn=get_sentry_dsn(client), profiles_sample_rate=1.0, traces_sample_rate=1.0
|
||||
):
|
||||
|
||||
def placeholder_fn():
|
||||
sum = 0
|
||||
for i in range(5):
|
||||
sum += i
|
||||
time.sleep(0.25)
|
||||
|
||||
with sentry_sdk.start_transaction(op="task", name="Test Transactions"):
|
||||
placeholder_fn()
|
||||
poll_for_response(
|
||||
f"{SENTRY_TEST_HOST}/api/0/organizations/sentry/events/?dataset=profiles&field=profile.id&project=1&statsPeriod=1h",
|
||||
client,
|
||||
lambda x: len(json.loads(x)["data"]) > 0,
|
||||
)
|
||||
poll_for_response(
|
||||
f"{SENTRY_TEST_HOST}/api/0/organizations/sentry/events/?dataset=spansIndexed&field=id&project=1&statsPeriod=1h",
|
||||
client,
|
||||
lambda x: len(json.loads(x)["data"]) > 0,
|
||||
)
|
||||
|
||||
|
||||
def test_customizations():
|
||||
commands = [
|
||||
[
|
||||
"docker",
|
||||
"compose",
|
||||
"--ansi",
|
||||
"never",
|
||||
"run",
|
||||
"--no-deps",
|
||||
"web",
|
||||
"bash",
|
||||
"-c",
|
||||
"if [ ! -e /created-by-enhance-image ]; then exit 1; fi",
|
||||
],
|
||||
[
|
||||
"docker",
|
||||
"compose",
|
||||
"--ansi",
|
||||
"never",
|
||||
"run",
|
||||
"--no-deps",
|
||||
"--entrypoint=/etc/sentry/entrypoint.sh",
|
||||
"sentry-cleanup",
|
||||
"bash",
|
||||
"-c",
|
||||
"if [ ! -e /created-by-enhance-image ]; then exit 1; fi",
|
||||
],
|
||||
[
|
||||
"docker",
|
||||
"compose",
|
||||
"--ansi",
|
||||
"never",
|
||||
"run",
|
||||
"--no-deps",
|
||||
"web",
|
||||
"python",
|
||||
"-c",
|
||||
"import ldap",
|
||||
],
|
||||
[
|
||||
"docker",
|
||||
"compose",
|
||||
"--ansi",
|
||||
"never",
|
||||
"run",
|
||||
"--no-deps",
|
||||
"--entrypoint=/etc/sentry/entrypoint.sh",
|
||||
"sentry-cleanup",
|
||||
"python",
|
||||
"-c",
|
||||
"import ldap",
|
||||
],
|
||||
]
|
||||
for command in commands:
|
||||
result = subprocess.run(command, check=False)
|
||||
if os.getenv("TEST_CUSTOMIZATIONS", "disabled") == "enabled":
|
||||
assert result.returncode == 0
|
||||
else:
|
||||
assert result.returncode != 0
|
Reference in New Issue
Block a user