diff --git a/.github/workflows/api-testing.yml b/.github/workflows/api-testing.yml new file mode 100644 index 0000000000..a5b4826bcb --- /dev/null +++ b/.github/workflows/api-testing.yml @@ -0,0 +1,119 @@ +name: Run integration tests against latest code + +on: + pull_request: + +env: + COLUMNS: 150 + ZO_ROOT_USER_EMAIL: root@example.com + ZO_ROOT_USER_PASSWORD: Complexpass#123 + ZO_BASE_URL: http://localhost:5080/ + +jobs: + build: + + runs-on: + labels: ubicloud-standard-16 + strategy: + matrix: + python-version: ["3.11"] + + steps: + + - name: Create k8s Kind Cluster + uses: helm/kind-action@v1.8.0 + with: + cluster_name: openobserve-ci-test + - name: Clone the current repo + uses: actions/checkout@v4 + - name: Print out the repo structure + run: ls -al + - name: Setup Rust Toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly-2023-12-24 + components: rustfmt,clippy,llvm-tools + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + cache-directories: + ./target + - name: Install Protoc + uses: arduino/setup-protoc@v2 + with: + version: "21.12" + - uses: actions/setup-node@v4 + with: + node-version: 18 + - name: Build binary + # run: cargo build --release --features mimalloc --target x86_64-unknown-linux-musl + run: cargo build --features mimalloc + # - run: mkdir -p bin ; cp target/x86_64-unknown-linux-musl/release/openobserve bin/openobserve + - run: mkdir -p bin ; cp target/debug/openobserve bin/openobserve + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver-opts: network=host + - name: Test locations + run: ls -al + - name: Build and push to local registry + uses: docker/build-push-action@v5 + with: + context: "." + file: ./tests/api-testing/ci/Dockerfile.openobserve + # push: true + outputs: type=docker,dest=/tmp/openobserve.tar + # tags: localhost:5000/openobserve/openobserve:latest-amd64 + tags: openobserve:latest-amd64 + cache-from: type=gha + cache-to: type=gha,mode=max + # - name: Inspect + # run: | + # docker buildx imagetools inspect localhost:5000/openobserve/openobserve:latest-amd64 + - name: Load built image into kind + # run: kind load docker-image localhost:5000/openobserve/openobserve:latest-amd64 --name openobserve-ci-test + run: kind load image-archive /tmp/openobserve.tar --name openobserve-ci-test + - name: Deploy openobserve + # run: kubectl create ns openobserve && kubectl apply -f https://raw.githubusercontent.com/zinclabs/openobserve/main/deploy/k8s/statefulset.yaml + run: kubectl create ns openobserve && kubectl apply -f ./tests/api-testing/ci/statefulset.yaml + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Wait for 10s, for the deployment to complete. + run: sleep 10s + shell: bash + - name: Check the services - 1 + run: kubectl get services --all-namespaces + - name: Check the services - 2 + run: kubectl get pods --all-namespaces + - name: Check the logs + run: kubectl logs openobserve-0 -n openobserve + - name: Port forward the 5080 + run: kubectl -n openobserve port-forward svc/openobserve 5080:5080 & + # You can test your matrix by printing the current Python version + - name: Display Python version + run: python -c "import sys; print(sys.version)" + - name: Enable caching and define a working directory + uses: eifinger/setup-rye@v1 + with: + enable-cache: true + working-directory: 'tests/api-testing/' + version: '0.16.0' + - name: Run tests + run: cd tests/api-testing/ && rye pin cpython@3.11.6 && rye sync && rye run pytest --force-sugar + + + # Try to test the openapi generator as well + # - name: openapi-generator test + # uses: openapi-generators/openapitools-generator-action@v1 + # with: + # generator: python + # openapi-url: http://localhost:5080/api-doc/openapi.json + # generator-tag: v7.0.1 + # command-args: '--package-name py-openobserve o ./py-openobserve --additional-properties=useSingleRequestParameter=true,packageVersion=2.0.0' + + + diff --git a/tests/api-testing/.gitignore b/tests/api-testing/.gitignore new file mode 100644 index 0000000000..ae8554dec4 --- /dev/null +++ b/tests/api-testing/.gitignore @@ -0,0 +1,10 @@ +# python generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# venv +.venv diff --git a/tests/api-testing/.python-version b/tests/api-testing/.python-version new file mode 100644 index 0000000000..375f5cabfe --- /dev/null +++ b/tests/api-testing/.python-version @@ -0,0 +1 @@ +3.11.6 diff --git a/tests/api-testing/Makefile b/tests/api-testing/Makefile new file mode 100644 index 0000000000..c95011f8a8 --- /dev/null +++ b/tests/api-testing/Makefile @@ -0,0 +1,12 @@ +.DEFAULT_GOAL := help + +.PHONY: format + +help: ## Show available options with this Makefile + @grep -F -h "##" $(MAKEFILE_LIST) | grep -v grep | awk 'BEGIN { FS = ":.*?##" }; { printf "%-18s %s\n", $$1,$$2 }' + +format: ## Run ruff formatter on the tests folder + ruff tests/ + +test: ## Run pytest + pytest tests/ diff --git a/tests/api-testing/README.md b/tests/api-testing/README.md new file mode 100644 index 0000000000..6bdd659f15 --- /dev/null +++ b/tests/api-testing/README.md @@ -0,0 +1,19 @@ +# pytest-openobserve + +This is a repo to test openobserve API endpoints. + +## Introduction: +The tests are running using `pytest` against alpha1 for now. +Idea is to parametrize it for the other endpoints like `production` as well. + +## Getting Started +- We use `rye` to manage the python version and environment - https://github.com/mitsuhiko/rye +- Once installed, simply run the following steps: + - `rye sync` + - `rye run pytest` + + +## TODOS: +- [ ] Parametrize tests to run against different environments +- [ ] Run the tests as cron-job every few hours or daily etc. for different environments +- [ ] Send slack-notification ( use github-actions ) in case something fails on `alpha1` or `production` endpoints. \ No newline at end of file diff --git a/tests/api-testing/ci/Dockerfile.openobserve b/tests/api-testing/ci/Dockerfile.openobserve new file mode 100644 index 0000000000..57a8718a6a --- /dev/null +++ b/tests/api-testing/ci/Dockerfile.openobserve @@ -0,0 +1,8 @@ +# syntax=docker/dockerfile:1 + +FROM public.ecr.aws/debian/debian:bookworm-slim as runtime +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates +RUN update-ca-certificates +COPY ./bin/openobserve / +RUN ["/openobserve", "init-dir", "-p", "/data/"] +CMD ["/openobserve"] diff --git a/tests/api-testing/ci/statefulset.yaml b/tests/api-testing/ci/statefulset.yaml new file mode 100644 index 0000000000..27583fe0be --- /dev/null +++ b/tests/api-testing/ci/statefulset.yaml @@ -0,0 +1,81 @@ +apiVersion: v1 +kind: Service +metadata: + name: openobserve + namespace: openobserve +spec: + clusterIP: None + selector: + app: openobserve + ports: + - name: http + port: 5080 + targetPort: 5080 + +--- + +# create statefulset +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: openobserve + namespace: openobserve + labels: + name: openobserve +spec: + serviceName: openobserve + replicas: 1 + selector: + matchLabels: + name: openobserve + app: openobserve + template: + metadata: + labels: + name: openobserve + app: openobserve + spec: + securityContext: + fsGroup: 2000 + runAsUser: 10000 + runAsGroup: 3000 + runAsNonRoot: true + # terminationGracePeriodSeconds: 0 + containers: + - name: openobserve + # image: localhost:5000/openobserve/openobserve:latest-amd64 + image: openobserve:latest-amd64 + env: + - name: ZO_ROOT_USER_EMAIL + value: root@example.com + - name: ZO_ROOT_USER_PASSWORD + value: Complexpass#123 + - name: ZO_DATA_DIR + value: /data + # command: ["/bin/bash", "-c", "while true; do sleep 1; done"] + imagePullPolicy: IfNotPresent + resources: + limits: + cpu: 4096m + memory: 2048Mi + requests: + cpu: 256m + memory: 50Mi + ports: + - containerPort: 5080 + name: http + volumeMounts: + - name: data + mountPath: /data + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: + - ReadWriteOnce + # storageClassName: default + # NOTE: You can increase the storage size + resources: + requests: + storage: 10Gi + diff --git a/tests/api-testing/pyproject.toml b/tests/api-testing/pyproject.toml new file mode 100644 index 0000000000..c6e518d55c --- /dev/null +++ b/tests/api-testing/pyproject.toml @@ -0,0 +1,29 @@ +[project] +name = "pytest-openobserve" +version = "0.1.0" +description = "Add your description here" +dependencies = [ + "pytest>=7.4.2", + "pytest-sugar>=0.9.7", + "pytest-pretty>=1.2.0", + "requests>=2.31.0", + "ruff>=0.1.8", +] +readme = "README.md" +requires-python = ">= 3.8" + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.rye] +managed = true +dev-dependencies = [ + "ruff>=0.1.8", +] + +[tool.hatch.metadata] +allow-direct-references = true + +[tool.hatch.build.targets.wheel] +packages = ["src/main"] diff --git a/tests/api-testing/requirements-dev.lock b/tests/api-testing/requirements-dev.lock new file mode 100644 index 0000000000..d2cd46b0fd --- /dev/null +++ b/tests/api-testing/requirements-dev.lock @@ -0,0 +1,30 @@ +# generated by rye +# use `rye lock` or `rye sync` to update this lockfile +# +# last locked with the following flags: +# pre: false +# features: [] +# all-features: false + +-e file:. +black==23.11.0 +certifi==2023.11.17 +charset-normalizer==3.3.2 +click==8.1.7 +idna==3.6 +iniconfig==2.0.0 +markdown-it-py==3.0.0 +mdurl==0.1.2 +mypy-extensions==1.0.0 +packaging==23.2 +pathspec==0.11.2 +platformdirs==4.0.0 +pluggy==1.3.0 +pygments==2.17.2 +pytest==7.4.3 +pytest-pretty==1.2.0 +pytest-sugar==0.9.7 +requests==2.31.0 +rich==13.7.0 +termcolor==2.3.0 +urllib3==2.1.0 diff --git a/tests/api-testing/requirements.lock b/tests/api-testing/requirements.lock new file mode 100644 index 0000000000..6cd5921a63 --- /dev/null +++ b/tests/api-testing/requirements.lock @@ -0,0 +1,25 @@ +# generated by rye +# use `rye lock` or `rye sync` to update this lockfile +# +# last locked with the following flags: +# pre: false +# features: [] +# all-features: false + +-e file:. +certifi==2023.11.17 +charset-normalizer==3.3.2 +idna==3.6 +iniconfig==2.0.0 +markdown-it-py==3.0.0 +mdurl==0.1.2 +packaging==23.2 +pluggy==1.3.0 +pygments==2.17.2 +pytest==7.4.3 +pytest-pretty==1.2.0 +pytest-sugar==0.9.7 +requests==2.31.0 +rich==13.7.0 +termcolor==2.3.0 +urllib3==2.1.0 diff --git a/tests/api-testing/src/main.py b/tests/api-testing/src/main.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/api-testing/tests/conftest.py b/tests/api-testing/tests/conftest.py new file mode 100644 index 0000000000..c5ddf65a8c --- /dev/null +++ b/tests/api-testing/tests/conftest.py @@ -0,0 +1,25 @@ +import requests +import pytest +import os + + +BASE_URL = os.environ["ZO_BASE_URL"] + + +@pytest.fixture +def create_session(): + """Create a session and return it.""" + + s = requests.Session() + username = os.environ["ZO_ROOT_USER_EMAIL"] + password = os.environ["ZO_ROOT_USER_PASSWORD"] + s.auth = (username, password) + s.post(BASE_URL) + return s + + +@pytest.fixture +def base_url(): + """Return the base URL.""" + + return BASE_URL diff --git a/tests/api-testing/tests/test_alerts.py b/tests/api-testing/tests/test_alerts.py new file mode 100644 index 0000000000..6446984236 --- /dev/null +++ b/tests/api-testing/tests/test_alerts.py @@ -0,0 +1,249 @@ + +def test_e2e_alerts(create_session, base_url): + """Running an E2E test for get all the alerts list.""" + + session = create_session + url = base_url + org_id = "default" + + resp_get_allalerts = session.get(f"{url}api/{org_id}/alerts") + + print(resp_get_allalerts.content) + assert ( + resp_get_allalerts.status_code == 200 + ), f"Get all alerts list 200, but got {resp_get_allalerts.status_code} {resp_get_allalerts.content}" + + +def test_e2e_destinations(create_session, base_url): + """Running an E2E test for get all the destination list under alerts.""" + + session = create_session + url = base_url + org_id = "default" + + resp_get_alldestinations = session.get(f"{url}api/{org_id}/alerts/destinations") + + print(resp_get_alldestinations.content) + assert ( + resp_get_alldestinations.status_code == 200 + ), f"Get all alerts list 200, but got {resp_get_alldestinations.status_code} {resp_get_alldestinations.content}" + + +def test_e2e_deleteinvaliddestination(create_session, base_url): + """Running an E2E test for deleting destination that does not exist .""" + + session = create_session + url = base_url + org_id = "default" + resp_delete_destination = session.delete( + f"{url}api/{org_id}/alerts/destinations/destinationname" + ) + assert ( + resp_delete_destination.status_code == 404 + ), f"Deleting this destination, but got {resp_delete_destination.status_code} {resp_delete_destination.content}" + + +def test_e2e_templates(create_session, base_url): + """Running an E2E test for get all the alerts list.""" + + session = create_session + url = base_url + org_id = "default" + + resp_get_alltemplates = session.get(f"{url}api/{org_id}/alerts/templates") + + print(resp_get_alltemplates.content) + assert ( + resp_get_alltemplates.status_code == 200 + ), f"Get all alerts list 200, but got {resp_get_alltemplates.status_code} {resp_get_alltemplates.content}" + + +# TODO - Change body and add 2 other testcases once bug #1702 is fixed +def test_e2e_templatescreation(create_session, base_url): + """Running an E2E test for get all the alerts list.""" + template_name = "newtemp" + + session = create_session + url = base_url + org_id = "default" + payload = {"body": "invalid", "ise2e": True, "name": template_name} + # create template under alerts + resp_get_alltemplates = session.post( + f"{url}api/{org_id}/alerts/templates/{template_name}", json=payload + ) + + print(resp_get_alltemplates.content) + assert ( + resp_get_alltemplates.status_code == 200 + ), f"Createtemplate 200, but got {resp_get_alltemplates.status_code} {resp_get_alltemplates.content}" + # delete created template + resp_delete_function = session.delete( + f"{base_url}api/{org_id}/alerts/templates/{template_name}" + ) + assert ( + resp_delete_function.status_code == 200 + ), f"Deleting this template, but got {resp_delete_function.status_code} {resp_delete_function.content}" + + +# TODO - Add this testcase once bug #1703 is fixed +# def test_e2e_templatesinvaliddelete(create_session,base_url): +# """Running an E2E test for get all the alerts list.""" +# template_name = "newtemp" + +# session = create_session +# url = base_url +# org_id = "e2e" +# resp_delete_function = session.delete(f"{base_url}api/{org_id}/alerts/templates/{template_name}") +# assert resp_delete_function.status_code == 200, f"Deleting this template, but got {resp_delete_function.status_code} {resp_delete_function.content}" + + +def test_e2e_createdestination(create_session, base_url): + """Running an E2E test for create a new destination.""" + + session = create_session + url = base_url + org_id = "default" + skip_tls_verify_value = False + + headers = {"Content-Type": "application/json", "Custom-Header": "value"} + + payload = { + "name": "pytesttemplate", + "body": """ + {{ + "text": "{alert_name} is active" + }} + """.format( + alert_name="pytestautomate" + ), + } + + # createtemplate + resp_create_destinations = session.post( + f"{url}api/{org_id}/alerts/templates/pytesttemplate", + json=payload, + headers=headers, + ) + print(resp_create_destinations.content) + + payload = { + "url": "www", + "method": "post", + "skip_tls_verify": skip_tls_verify_value, + "template": "pytesttemplate", + "headers": {"test": "test"}, + } + destination_name = "py-destinations" + # create destination + resp_create_destinations = session.post( + f"{url}api/{org_id}/alerts/destinations/{destination_name}", + json=payload, + headers=headers, + ) + print(resp_create_destinations.content) + # get destination + resp_create_destinations = session.get( + f"{url}api/{org_id}/alerts/destinations/{destination_name}", + json=payload, + headers=headers, + ) + print(resp_create_destinations.content) + assert ( + resp_create_destinations.status_code == 200 + ), f"Get all alerts list 200, but got {resp_create_destinations.status_code} {resp_create_destinations.content}" + + # ingest logs + session = create_session + url = base_url + org_id = "default" + stream_name = "newpy_tests" + payload = [ + { + "Athlete": "newtemp", + "City": "Athens", + "Country": "HUN", + "Discipline": "Swimming", + "Sport": "Aquatics", + "Year": 1896, + }, + { + "Athlete": "HERSCHMANN", + "City": "Athens", + "Country": "CHN", + "Discipline": "Swimming", + "Sport": "Aquatics", + "Year": 1896, + }, + ] + + resp_create_logstream = session.post( + f"{url}api/{org_id}/{stream_name}/_json", json=payload + ) + + print(resp_create_logstream.content) + assert ( + resp_create_logstream.status_code == 200 + ), f"Get all alerts list 200, but got {resp_create_logstream.status_code} {resp_create_logstream.content}" + + stream_name = "newpy_tests" + alert_name = "py-alert" + is_real_time = False + payload = { + "name": "pytest-alert", + "stream_type": "logs", + "stream_name": "newpy_tests", + "is_real_time": is_real_time, + "query_condition": { + "conditions": [ + { + "column": "city", + "operator": "=", + "value": "200", + "id": "ebab5c0f-e78b-46b4-900a-22eb8a1f662c", + } + ], + "sql": "", + "promql": None, + "type": "custom", + "aggregation": None, + }, + "trigger_condition": { + "period": 10, + "operator": ">=", + "threshold": 3, + "silence": 10, + }, + "destinations": ["py-destinations"], + "context_attributes": {}, + "enabled": True, + "description": "", + } + resp_create_alert = session.post( + f"{url}api/{org_id}/{stream_name}/alerts/{alert_name}", + json=payload, + headers=headers, + ) + print(resp_create_alert.content) + assert ( + resp_create_alert.status_code == 200 + ), f"Get all alerts list 200, but got {resp_create_alert.status_code} {resp_create_alert.content}" + resp_delete_alert = session.delete( + f"{url}api/{org_id}/{stream_name}/alerts/{alert_name}?type=logs" + ) + assert ( + resp_delete_alert.status_code == 200 + ), f"Deleting this function, but got {resp_delete_alert.status_code} {resp_delete_alert.content}" + + resp_delete_destination = session.delete( + f"{url}api/{org_id}/alerts/destinations/{destination_name}" + ) + assert ( + resp_delete_destination.status_code == 200 + ), f"Deleting this function, but got {resp_delete_destination.status_code} {resp_delete_destination.content}" + + resp_delete_template = session.delete( + f"{url}api/{org_id}/alerts/templates/pytesttemplate" + ) + assert ( + resp_delete_template.status_code == 200 + ), f"Deleting this function, but got {resp_delete_template.status_code} {resp_delete_template.content}" diff --git a/tests/api-testing/tests/test_folders.py b/tests/api-testing/tests/test_folders.py new file mode 100644 index 0000000000..e0687527af --- /dev/null +++ b/tests/api-testing/tests/test_folders.py @@ -0,0 +1,241 @@ +def delete_folder(session, base_url, org_id, folder_id): + resp_delete_folder = session.delete(f"{base_url}api/{org_id}/folders/{folder_id}") + assert ( + resp_delete_folder.status_code == 200 + ), f"Deleting this folder: Expected 200, but got {resp_delete_folder.status_code} {resp_delete_folder.content}" + + +def test_e2e_alldashboards(create_session, base_url): + """Running an E2E test for all dashboards.""" + + session = create_session + org_id = "default" + + resp_get_alldashboards = session.get(f"{base_url}api/{org_id}/dashboards") + + print(resp_get_alldashboards.content) + assert ( + resp_get_alldashboards.status_code == 200 + ), f"Get all functions list 200, but got {resp_get_alldashboards.status_code} {resp_get_alldashboards.content}" + + +def test_e2e_allfolders(create_session, base_url): + """Running an E2E test for all folders.""" + + session = create_session + org_id = "default" + + resp_get_allfolders = session.get(f"{base_url}api/{org_id}/folders") + + print(resp_get_allfolders.content) + assert ( + resp_get_allfolders.status_code == 200 + ), f"Get all functions list 200, but got {resp_get_allfolders.status_code} {resp_get_allfolders.content}" + + +def test_e2e_createdeletefolder(create_session, base_url): + """Running an E2E test for create and delete folder.""" + + session = create_session + # Create a folder + org_id = "default" + url = base_url + payload = {"description": "newfoldernvp", "name": "pytest-automationtests"} + resp_create_folder = session.post(f"{url}api/{org_id}/folders", json=payload) + + print(resp_create_folder.content) + + folder_id = resp_create_folder.json()["folderId"] + + assert ( + resp_create_folder.status_code == 200 + ), f"Expected 200, but got {resp_create_folder.status_code} {resp_create_folder.content}" + payload = { + "description": "folderupdated", + "folderId": folder_id, + "name": "pytest-automation", + } + folder_id = resp_create_folder.json()["folderId"] + # Update folder + resp_update_folder = session.put( + f"{base_url}api/{org_id}/folders/{folder_id}", json=payload + ) + assert ( + resp_update_folder.status_code == 200 + ), f"updating this folder, but got {resp_update_folder.status_code} {resp_update_folder.content}" + print(resp_update_folder.content) + # Delete Folder + resp_delete_folder = session.delete(f"{base_url}api/{org_id}/folders/{folder_id}") + assert ( + resp_delete_folder.status_code == 200 + ), f"Deleting this folder, but got {resp_delete_folder.status_code} {resp_delete_folder.content}" + + +# TODO - Change this testcase when the bug is fixed 1687 +# def test_e2e_createfolderwithblankspace(create_session): +# """Running an E2E test for create and delete folder.""" + +# session = create_session +# # Create a folder +# org_id = "e2e" +# payload = { +# "description": "newfoldernvp", +# "name": " " +# } +# resp_create_folder = session.post(f"https://alpha1.gke.zinclabs.dev/api/{org_id}/folders", json=payload) + +# print(resp_create_folder.content) + +# folder_id = resp_create_folder.json()["folderId"] + +# assert resp_create_folder.status_code == 200, f"Expected 200, but got {resp_create_folder.status_code} {resp_create_folder.content}" +# resp_delete_folder = session.delete(f"https://alpha1.gke.zinclabs.dev/api/{org_id}/folders/{folder_id}") +# assert resp_delete_folder.status_code == 200, f"Deleting this folder, but got {resp_delete_folder.status_code} {resp_delete_folder.content}" + + +def test_e2e_createdeletedashboard(create_session, base_url): + """Running an E2E test for create and delete dashboard.""" + + session = create_session + # Create a dashboard + org_id = "default" + payload = {"description": "pydashboards", "title": "pytestdashboard"} + + resp_create_dashboard = session.post( + f"{base_url}api/{org_id}/dashboards", json=payload + ) + + print(resp_create_dashboard.content) + + # dashboard_id = resp_create_dashboard.json()["dashboardId"] + + assert ( + resp_create_dashboard.status_code == 200 + ), f"Expected 200, but got {resp_create_dashboard.status_code} {resp_create_dashboard.content}" + payload = { + "title": "testpy", + "dashboardId": "", + "description": "updatedashboard", + "role": "", + "owner": "root@alpha1.com", + "created": "2023-10-19T14:08:48.090Z", + "panels": [], + } + dashboard_id = resp_create_dashboard.json()["v1"]["dashboardId"] + resp_update_dashboard = session.put( + f"{base_url}api/{org_id}/dashboards/{dashboard_id}", json=payload + ) + assert ( + resp_update_dashboard.status_code == 200 + ), f"updating this folder, but got {resp_update_dashboard.status_code} {resp_update_dashboard.content}" + resp_delete_dashboard = session.delete( + f"{base_url}api/{org_id}/dashboards/{dashboard_id}" + ) + assert ( + resp_delete_dashboard.status_code == 200 + ), f"Deleting this dashboard, but got {resp_delete_dashboard.status_code} {resp_delete_dashboard.content}" + + +# TODO - Change this testcase when the bug is fixed 1687 +# def test_e2e_createdeletedashboard(create_session): +# """Running an E2E test for create and delete dashboard.""" + +# session = create_session +# # Create a dashboard +# org_id = "e2e" +# payload = { +# "description": "pydashboards", +# "title": " " +# } + +# resp_create_dashboard = session.post(f"https://alpha1.gke.zinclabs.dev/api/{org_id}/dashboards", json=payload) + +# print(resp_create_dashboard.content) + + +# assert resp_create_dashboard.status_code == 200, f"Expected 200, but got {resp_create_dashboard.status_code} {resp_create_dashboard.content}" +# dashboard_id = resp_create_dashboard.json()["v1"]["dashboardId"] +# resp_delete_dashboard = session.delete(f"https://alpha1.gke.zinclabs.dev/api/{org_id}/dashboards/{dashboard_id}") +# assert resp_delete_dashboard.status_code == 200, f"Deleting this dashboard, but got {resp_delete_dashboard.status_code} {resp_delete_dashboard.content}" + + +def test_e2e_movedashboard(create_session, base_url): + """Running an E2E test for create 2 folders, move dashboards and delete dashboards and folders.""" + + session = create_session + # Create a folder + org_id = "default" + url = base_url + # create folder a + + payload = {"description": "newfoldernvp", "name": "pytest-a"} + resp_create_folder = session.post(f"{url}api/{org_id}/folders", json=payload) + + print(resp_create_folder.content) + + folder_id_a = resp_create_folder.json()["folderId"] + assert ( + resp_create_folder.status_code == 200 + ), f"unable to create folder 1, but got {resp_create_folder.status_code} {resp_create_folder.content}" + + # create folder b + payload = {"description": "newfoldernvp", "name": "pytest-b"} + resp_create_folder = session.post(f"{url}api/{org_id}/folders", json=payload) + + print(resp_create_folder.content) + + folder_id_b = resp_create_folder.json()["folderId"] + + assert ( + resp_create_folder.status_code == 200 + ), f"unable to create folder b, but got {resp_create_folder.status_code} {resp_create_folder.content}" + + # create dashboard + org_id = "default" + payload = { + "title": "testpy", + "dashboardId": "", + "description": "test", + "role": "", + "owner": "root@alpha1.com", + "created": "2023-10-19T14:08:48.090Z", + "panels": [], + } + resp_create_dashboard = session.post( + f"{base_url}api/{org_id}/dashboards?folder={folder_id_a}", json=payload + ) + print(resp_create_dashboard.content) + try: + dashboard_id = resp_create_dashboard.json()["v1"]["dashboardId"] + except KeyError: + dashboard_id = None + assert ( + resp_create_dashboard.status_code == 200 + ), f"Created a dashboard 200, but got {resp_create_dashboard.status_code} {resp_create_dashboard.content}" + try: + dashboard_id = resp_create_dashboard.json()["v1"]["dashboardId"] + except KeyError: + dashboard_id = None + payload = {"from": folder_id_a, "to": folder_id_b} + # move dashboard from folder A to folder B + resp_move_dashboard = session.put( + f"{base_url}api/{org_id}/folders/dashboards/{dashboard_id}", json=payload + ) + assert ( + resp_move_dashboard.status_code == 200 + ), f"Moved dashboard 200, but got {resp_move_dashboard.status_code} {resp_move_dashboard.content}" + try: + dashboard_id = resp_create_dashboard.json()["v1"]["dashboardId"] + except KeyError: + dashboard_id = None + print(resp_move_dashboard.content) + # Delete Dashboard from Folder B + resp_delete_dashboard = session.delete( + f"{base_url}api/{org_id}/dashboards/{dashboard_id}?folder={folder_id_b}" + ) + assert ( + resp_delete_dashboard.status_code == 200 + ), f"Deleting this dashboard, but got {resp_delete_dashboard.status_code} {resp_delete_dashboard.content}" + # Delete folders + delete_folder(session, base_url, org_id, folder_id_a) + delete_folder(session, base_url, org_id, folder_id_b) diff --git a/tests/api-testing/tests/test_functions.py b/tests/api-testing/tests/test_functions.py new file mode 100644 index 0000000000..cd117312a1 --- /dev/null +++ b/tests/api-testing/tests/test_functions.py @@ -0,0 +1,245 @@ +def test_e2e_folder(create_session, base_url): + """Running an E2E test for all xfunctions.""" + + session = create_session + org_id = "default" + + resp_get_allfunctions = session.get(f"{base_url}api/{org_id}/functions") + + print(resp_get_allfunctions.content) + assert ( + resp_get_allfunctions.status_code == 200 + ), f"Get all functions list 200, but got {resp_get_allfunctions.status_code} {resp_get_allfunctions.content}" + + +def test_e2e_createdeletefunction(create_session, base_url): + """Running an E2E test for create and delete functions.""" + + session = create_session + # Create a function + org_id = "default" + payload = { + "function": ".a=190025552", + "name": "pytestfunction", + "params": "row", + "transType": 0, + } + + resp_create_function = session.post( + f"{base_url}api/{org_id}/functions", json=payload + ) + + print(resp_create_function.content) + assert ( + resp_create_function.status_code == 200 + ), f"Expected 200, but got {resp_create_function.status_code} {resp_create_function.content}" + resp_delete_function = session.delete( + f"{base_url}api/{org_id}/functions/pytestfunction" + ) + assert ( + resp_delete_function.status_code == 200 + ), f"Deleting this function, but got {resp_delete_function.status_code} {resp_delete_function.content}" + + +def test_e2e_invalidfunction(create_session, base_url): + """Running an E2E test for invalid function creation""" + + session = create_session + # Create a function + org_id = "default" + payload = {"name": "...", "function": "...", "params": "row", "transType": 0} + + resp_create_function = session.post( + f"{base_url}api/{org_id}/functions", json=payload + ) + + print(resp_create_function.content) + assert ( + resp_create_function.status_code == 400 + ), f"Invalid function creation, but got {resp_create_function.status_code} {resp_create_function.content}" + + +def test_e2e_updatingfunction(create_session, base_url): + """Running an E2E test for update and delete an existing function.""" + + session = create_session + # Create a function + org_id = "default" + payload = { + "name": "pytestfunctions", + "function": ".a=190022", + "params": "row", + "transType": 0, + } + + resp_create_function = session.post( + f"{base_url}api/{org_id}/functions", json=payload + ) + + print(resp_create_function.content) + assert ( + resp_create_function.status_code == 200 + ), f"Expected 200, but got {resp_create_function.status_code} {resp_create_function.content}" + session = create_session + # Create a function + org_id = "default" + payload = { + "name": "pytestfunctions", + "function": ".a=1900", + "params": "row", + "transType": 0, + } + resp_update_function = session.put( + f"{base_url}api/{org_id}/functions/pytestfunctions", + json=payload, + ) + print(resp_create_function.content) + assert ( + resp_update_function.status_code == 200 + ), f"Updating this function, but got {resp_update_function.status_code} {resp_update_function.content}" + resp_delete_function = session.delete( + f"{base_url}api/{org_id}/functions/pytestfunctions" + ) + assert ( + resp_delete_function.status_code == 200 + ), f"Deleting this function, but got {resp_delete_function.status_code} {resp_delete_function.content}" + + +def test_e2e_duplicatefunction(create_session, base_url): + """Running an E2E test for function already exists.""" + + session = create_session + # Create a function + org_id = "default" + payload = { + "name": "pytestfunctions", + "function": ".a=190022", + "params": "row", + "transType": 0, + } + + resp_create_function = session.post( + f"{base_url}api/{org_id}/functions", json=payload + ) + + print(resp_create_function.content) + assert ( + resp_create_function.status_code == 200 + ), f"Expected 200, but got {resp_create_function.status_code} {resp_create_function.content}" + resp_delete_function = session.delete( + f"{base_url}api/{org_id}/functions/pytestfunction" + ) + session = create_session + # Create a function + org_id = "default" + payload = { + "name": "pytestfunctions", + "function": ".a=190022", + "params": "row", + "transType": 0, + } + + resp_create_function = session.post( + f"{base_url}api/{org_id}/functions", json=payload + ) + + print(resp_create_function.content) + assert ( + resp_create_function.status_code == 400 + ), f"Expected 400 function already exists, but got {resp_create_function.status_code} {resp_create_function.content}" + resp_delete_function = session.delete( + f"{base_url}api/{org_id}/functions/pytestfunctions" + ) + assert ( + resp_delete_function.status_code == 200 + ), f"Deleting this function, but got {resp_delete_function.status_code} {resp_delete_function.content}" + + +def test_e2e_functionnotfound(create_session, base_url): + """Running an E2E test for function not found.""" + + session = create_session + # Create a function + org_id = "default" + + resp_delete_function = session.delete( + f"{base_url}api/{org_id}/functions/pytestfunctionsss" + ) + assert ( + resp_delete_function.status_code == 404 + ), f"Function not found, but got {resp_delete_function.status_code} {resp_delete_function.content}" + + +def test_e2e_allfunctionstreams(create_session, base_url): + """Running an E2E test for all streams under functions.""" + + session = create_session + org_id = "default" + stream_name = "test" + + resp_get_streamfunction = session.get( + f"{base_url}api/{org_id}/{stream_name}/functions" + ) + + print(resp_get_streamfunction.content) + assert ( + resp_get_streamfunction.status_code == 200 + ), f"Get all functions streams list 200, but got {resp_get_streamfunction.status_code} {resp_get_streamfunction.content}" + + +def test_e2e_addDeleteStreamFunction(create_session, base_url): + """Running an E2E test for add stream to a function and delete.""" + + session = create_session + org_id = "default" + stream_name = "test" + + # Create a function + org_id = "default" + payload = { + "function": ".a=190025552", + "name": "pytestfunction", + "params": "row", + "transType": 0, + } + + resp_create_function = session.post( + f"{base_url}api/{org_id}/functions", json=payload + ) + + print(resp_create_function.content) + assert ( + resp_create_function.status_code == 200 + ), f"Expected 200, but got {resp_create_function.status_code} {resp_create_function.content}" + + resp_get_streamfunction = session.get( + f"{base_url}api/{org_id}/{stream_name}/functions" + ) + + print(resp_get_streamfunction.content) + assert ( + resp_get_streamfunction.status_code == 200 + ), f"Get all functions streams list 200, but got {resp_get_streamfunction.status_code} {resp_get_streamfunction.content}" + + payload = {"order": 2} + resp_add_streamfunction = session.post( + f"{base_url}api/{org_id}/{stream_name}/functions/pytestfunction", + json=payload, + ) + + print(resp_add_streamfunction.content) + assert ( + resp_add_streamfunction.status_code == 200 + ), f"Add stream to function 200, but got {resp_add_streamfunction.status_code} {resp_add_streamfunction.content}" + resp_delete_streamfunction = session.delete( + f"{base_url}api/{org_id}/{stream_name}/functions/pytestfunction" + ) + assert ( + resp_delete_streamfunction.status_code == 200 + ), f"Deleted the function from stream 200, but got {resp_delete_streamfunction.status_code} {resp_delete_streamfunction.content}" + resp_delete_function = session.delete( + f"{base_url}api/{org_id}/functions/pytestfunction" + ) + assert ( + resp_delete_function.status_code == 200 + ), f"Deleting this function, but got {resp_delete_function.status_code} {resp_delete_function.content}" diff --git a/tests/api-testing/tests/test_kinesis.py b/tests/api-testing/tests/test_kinesis.py new file mode 100644 index 0000000000..f6d0160341 --- /dev/null +++ b/tests/api-testing/tests/test_kinesis.py @@ -0,0 +1,95 @@ +import pytest + + +@pytest.mark.skip(reason="no way of currently testing this") +def test_e2e_ingestkineses(create_session, base_url): + """Running an E2E ingest data using valid access key""" + + session = create_session + url = base_url + org_id = "e2e" + access_key = "cm9vdEBhbHBoYTEuY29tOlgxT1JaSFNlckhJdDhjTEI=" + headers = { + "X-Amz-Firehose-Access-Key": access_key, + "Content-Type": "application/json", + } + payload = { + "records": [ + { + "data": "H4sICE6PQmUAA2YxLmpzb24ARY/NCsIwEITvPsWSs0g9+NPeRFovVcEWPIhIbNcm2CYlSS0ivrtprPWykPmGycxrBEAq1JoWmD5rJAGQ9X6XHvbxZRsmyWoTknHnka1A5Wgpm7ylJmOxLPQXlrLYKNnUHR+UxCik1V/SzVVniteGSxHx0qDSFp7OP3/4QGGcZAWAl7sW8XzIcG/DbV9Dq+636dxfLufebOF7njc4+j2u7TGGfg/0ewJYM8zuXBTAkJaGgbxBbiO5oF03iLhCJjVOiAt823sevT+zyFHsKgEAAA==" + } + ], + "requestId": "9ec6b6f8-8b93-4734-8521-3e78a9517f5f", + "timestamp": 1698860579000, + } + + resp_ingestkineses = session.post( + f"{url}aws/default/{org_id}/_kinesis_firehose", json=payload, headers=headers + ) + + print(resp_ingestkineses.content) + assert ( + resp_ingestkineses.status_code == 200 + ), f"Creating a user 200, but got {resp_ingestkineses.status_code} {resp_ingestkineses.content}" + + +@pytest.mark.skip(reason="no way of currently testing this") +def test_e2e_invalidingestkineses(create_session, base_url): + """Running an E2E test for incorrect access key while data ingestion.""" + + session = create_session + url = base_url + org_id = "e2e" + access_key = "cm9vdEBhbHBoYTEuY29tOlgxT1JaSFNlckh" + headers = { + "X-Amz-Firehose-Access-Key": access_key, + "Content-Type": "application/json", + } + payload = { + "records": [ + { + "data": "H4sICE6PQmUAA2YxLmpzb24ARY/NCsIwEITvPsWSs0g9+NPeRFovVcEWPIhIbNcm2CYlSS0ivrtprPWykPmGycxrBEAq1JoWmD5rJAGQ9X6XHvbxZRsmyWoTknHnka1A5Wgpm7ylJmOxLPQXlrLYKNnUHR+UxCik1V/SzVVniteGSxHx0qDSFp7OP3/4QGGcZAWAl7sW8XzIcG/DbV9Dq+636dxfLufebOF7njc4+j2u7TGGfg/0ewJYM8zuXBTAkJaGgbxBbiO5oF03iLhCJjVOiAt823sevT+zyFHsKgEAAA==" + } + ], + "requestId": "9ec6b6f8-8b93-4734-8521-3e78a9517f5f", + "timestamp": 1698860579000, + } + + resp_ingestkineses = session.post( + f"{url}aws/default/{org_id}/_kinesis_firehose", json=payload, headers=headers + ) + + print(resp_ingestkineses.content) + assert ( + resp_ingestkineses.status_code == 401 + ), f"Creating a user 200, but got {resp_ingestkineses.status_code} {resp_ingestkineses.content}" + + +@pytest.mark.skip(reason="no way of currently testing this") +def test_e2e_incorrertdatakineses(create_session, base_url): + """Running an E2E test for missing request id in response.""" + + session = create_session + url = base_url + org_id = "e2e" + access_key = "cm9vdEBhbHBoYTEuY29tOlgxT1JaSFNlckhJdDhjTEI=" + headers = { + "X-Amz-Firehose-Access-Key": access_key, + "Content-Type": "application/json", + } + payload = { + "records": [ + { + "data": "H4sICE6PQmUAA2YxLmpzb24ARY/NCsIwEITvPsWSs0g9+NPeRFovVcEWPIhIbNcm2CYlSS0ivrtprPWykPmGycxrBEAq1JoWmD5rJAGQ9X6XHvbxZRsmyWoTknHnka1A5Wgpm7ylJmOxLPQXlrLYKNnUHR+UxCik1V/SzVVniteGSxHx0qDSFp7OP3/4QGGcZAWAl7sW8XzIcG/DbV9Dq+636dxfLufebOF7njc4+j2u7TGGfg/0ewJYM8zuXBTAkJaGgbxBbiO5oF03iLhCJjVOiAt823sevT+zyFHsKgEAAA==" + } + ], + } + + resp_ingestkineses = session.post( + f"{url}aws/default/{org_id}/_kinesis_firehose", json=payload, headers=headers + ) + + print(resp_ingestkineses.content) + assert ( + resp_ingestkineses.status_code == 400 + ), f"Missing requestID 200 , but got {resp_ingestkineses.status_code} {resp_ingestkineses.content}" diff --git a/tests/api-testing/tests/test_logs.py b/tests/api-testing/tests/test_logs.py new file mode 100644 index 0000000000..00bbcbdbf3 --- /dev/null +++ b/tests/api-testing/tests/test_logs.py @@ -0,0 +1,218 @@ +def test_e2e_ingestlogs(create_session, base_url): + """Running an E2E test logs ingestion.""" + + session = create_session + url = base_url + org_id = "default" + stream_name = "newpy-tests" + payload = [ + { + "Athlete": "newtemp", + "City": "Athens", + "Country": "HUN", + "Discipline": "Swimming", + "Sport": "Aquatics", + "Year": 1896, + }, + { + "Athlete": "HERSCHMANN", + "City": "Athens", + "Country": "CHN", + "Discipline": "Swimming", + "Sport": "Aquatics", + "Year": 1896, + }, + ] + + resp_create_logstream = session.post( + f"{url}api/{org_id}/{stream_name}/_json", json=payload + ) + + print(resp_create_logstream.content) + assert ( + resp_create_logstream.status_code == 200 + ), f"Get all alerts list 200, but got {resp_create_logstream.status_code} {resp_create_logstream.content}" + + +def test_e2e_nostreamname(create_session, base_url): + """Running an E2E test for adding logs without stream name.""" + + session = create_session + url = base_url + org_id = "default" + stream_name = "" + payload = [ + { + "Athlete": "newtemp", + "City": "Athens", + "Country": "HUN", + "Discipline": "Swimming", + "Sport": "Aquatics", + "Year": 1896, + }, + { + "Athlete": "HERSCHMANN", + "City": "Athens", + "Country": "CHN", + "Discipline": "Swimming", + "Sport": "Aquatics", + "Year": 1896, + }, + ] + + resp_create_logstream = session.post( + f"{url}api/{org_id}/{stream_name}/_json", json=payload + ) + print(resp_create_logstream.content) + assert ( + resp_create_logstream.status_code == 404 + ), f"Get all alerts list 200, but got {resp_create_logstream.status_code} {resp_create_logstream.content}" + + +def test_e2e_invalidstreamname(create_session, base_url): + """Running an E2E test for adding invalid stream name.""" + + session = create_session + url = base_url + org_id = "default" + stream_name = "newpy#$#$#$#$2@2" + payload = [ + { + "Athlete": "newtemp", + "City": "Athens", + "Country": "HUN", + "Discipline": "Swimming", + "Sport": "Aquatics", + "Year": 1896, + }, + { + "Athlete": "HERSCHMANN", + "City": "Athens", + "Country": "CHN", + "Discipline": "Swimming", + "Sport": "Aquatics", + "Year": 1896, + }, + ] + resp_create_logstream = session.post( + f"{url}api/{org_id}/{stream_name}/_json", json=payload + ) + + print(resp_create_logstream.content) + assert ( + resp_create_logstream.status_code == 404 + ), f"Get all alerts list 200, but got {resp_create_logstream.status_code} {resp_create_logstream.content}" + + +def test_e2e_vrl(create_session, base_url): + """Running an E2E test for search log query.""" + + session = create_session + org_id = "default" + stream_name = "gke_fluentbit" + access_key = "f=" + headers = { + "Authorization": f"Basic {access_key}", + "Content-Type": "application/json", + } + + payload = [ + { + "query": { + "sql": f'select * from "{stream_name}" ', + "start_time": 1700629279639000, + "end_time": 1700630179639000, + "from": 0, + "size": 150, + "query_fn": "LmEgPTEgCiAu", + }, + "aggs": { + "histogram": "select histogram(_timestamp, '10 second') AS zo_sql_key, count(*) AS zo_sql_num from query GROUP BY zo_sql_key ORDER BY zo_sql_key" + }, + } + ] + + resp_get_allalerts = session.post( + f"{base_url}web/logs?stream={stream_name}&period=15m&refresh=0&org_identifier={org_id}", + json=payload, + headers=headers, + ) + + print(resp_get_allalerts.content) + assert ( + resp_get_allalerts.status_code == 200 + ), f"Get all alerts list 200, but got {resp_get_allalerts.status_code} {resp_get_allalerts.content}" + + +def test_e2e_getallstreams(create_session, base_url): + """Running an E2E test for get all the streams list.""" + + session = create_session + url = base_url + org_id = "default" + + resp_get_allstreams = session.get(f"{url}api/{org_id}/streams") + + print(resp_get_allstreams.content) + assert ( + resp_get_allstreams.status_code == 200 + ), f"Get all alerts list 200, but got {resp_get_allstreams.status_code} {resp_get_allstreams.content}" + + +def test_e2e_getschema(create_session, base_url): + """Running an E2E test for get stream schema.""" + + session = create_session + url = base_url + org_id = "default" + + resp_get_streamschema = session.get(f"{url}api/{org_id}/newpy_tests/schema") + + print(resp_get_streamschema.content) + assert ( + resp_get_streamschema.status_code == 200 + ), f"Get all alerts list 200, but got {resp_get_streamschema.status_code} {resp_get_streamschema.content}" + + +def test_e2e_deleteinvalidstreams(create_session, base_url): + """Running an E2E test for delete invalid stream.""" + + session = create_session + url = base_url + org_id = "default" + + resp_get_deletestreams = session.delete(f"{url}api/{org_id}/invalidstream") + + print(resp_get_deletestreams.content) + assert ( + resp_get_deletestreams.status_code == 404 + ), f"Get all alerts list 200, but got {resp_get_deletestreams.status_code} {resp_get_deletestreams.content}" + + +def test_e2e_incorrectstreamesettings(create_session, base_url): + """Running an E2E test for invalid stream settings.""" + + session = create_session + url = base_url + org_id = "default" + resp_get_streamssettings = session.post(f"{url}api/{org_id}/newpy_tests/settings") + + print(resp_get_streamssettings.content) + assert ( + resp_get_streamssettings.status_code == 400 + ), f"Get all alerts list 200, but got {resp_get_streamssettings.status_code} {resp_get_streamssettings.content}" + + +def test_e2e_deletevalidstreams(create_session, base_url): + """Running an E2E test for delete streams.""" + + session = create_session + url = base_url + org_id = "default" + + resp_get_allstreams = session.delete(f"{url}api/{org_id}/newpy_tests") + + print(resp_get_allstreams.content) + assert ( + resp_get_allstreams.status_code == 200 + ), f"Get all alerts list 200, but got {resp_get_allstreams.status_code} {resp_get_allstreams.content}" diff --git a/tests/api-testing/tests/test_metrics.py b/tests/api-testing/tests/test_metrics.py new file mode 100644 index 0000000000..12fccdb88e --- /dev/null +++ b/tests/api-testing/tests/test_metrics.py @@ -0,0 +1,124 @@ +import pytest + + +@pytest.fixture +def sample_payload(): + return [ + { + "__name__": "cpu", + "__type__": "gauge", + "namespace": "ziox", + "container": "zo1", + "_timestamp": 1691643770347, + "value": 1.31, + }, + { + "__name__": "cpu", + "__type__": "gauge", + "namespace": "ziox", + "container": "zo1", + "_timestamp": 1691643770347, + "value": 1.41, + }, + ] + + +def test_e2e_metrics_ingest_validjson(create_session, base_url, sample_payload): + """Running an E2E test for missing request id in response.""" + + session = create_session + url = base_url + org_id = "default" + + resp_ingestmetrics = session.post( + f"{url}api/{org_id}/ingest/metrics/_json", json=sample_payload + ) + + print(resp_ingestmetrics.content) + assert ( + resp_ingestmetrics.status_code == 200 + ), f"valid json upload 200 , but got {resp_ingestmetrics.status_code} {resp_ingestmetrics.content}" + + +def test_e2e_metrics_ingest_invalijson(create_session, base_url): + """Running an E2E test for missing request id in response.""" + + session = create_session + url = base_url + org_id = "default" + access_key = "cm9vdEBhbHBoYTEuY29tOlJnNmpQWlRqUHFHNkVFSm8=" + headers = { + "Authorization": f"Basic {access_key}", + "Content-Type": "application/json", + } + + payload = [ + { + "__name__": "cpu", + "__type__": "gauge", + "namespace": "ziox", + "container": "zo1", + "_timestamp": 1691643770347, + "value": 1.31, + }, + {}, + ] + + resp_ingestmetrics = session.post( + f"{url}api/{org_id}/ingest/metrics/_json", json=payload, headers=headers + ) + + print(resp_ingestmetrics.content) + assert ( + resp_ingestmetrics.status_code == 400 + ), f"Invalid json upload 400, but got {resp_ingestmetrics.status_code} {resp_ingestmetrics.content}" + + +# def test_e2e_metrics_query(create_session, base_url): +# """Running an E2E test for metrics query.""" + +# session = create_session +# url = base_url +# org_id = "default" +# access_key = "ZTJlLnRlc3RpbmdAZXhhbXBsZS5jb206NnJCWGlWNmQxMmJ4SGdHdQ==" +# headers = { +# "Authorization": f"Basic {access_key}", +# "Content-Type": "application/json" +# } + +# resp_metricsquery = session.get(f"{base_url}api/e2e/prometheus/api/v1/format_query?query=%7B__name__%3D%22prometheus_tsdb_tombstone_cleanup_seconds_count%22%7D", headers=headers) + +# print(resp_metricsquery.content) +# assert resp_metricsquery.status_code == 200, f"valid query upload 200, but got {resp_metricsquery.status_code} {resp_metricsquery.content}" + + +def test_e2e_metrics_invalidquery(create_session, base_url): + """Running an E2E test for metrics query.""" + + session = create_session + org_id = "default" + + resp_metricsquery = session.get( + f"{base_url}api/{org_id}/prometheus/api/v1/format_query?query=%7B__name__%3D%22%22%7D" + ) + + print(resp_metricsquery.content) + assert ( + resp_metricsquery.status_code == 400 + ), f"Invalid query upload 400, but got {resp_metricsquery.status_code} {resp_metricsquery.content}" + + +def test_e2e_metrics_query(create_session, base_url): + """Running an E2E test for metrics query.""" + + session = create_session + org_id = "default" + + resp_metricsquery = session.get( + f"{base_url}api/{org_id}/prometheus/api/v1/format_query?query=%7B__name__%3D%22prometheus_tsdb_tombstone_cleanup_seconds_count%22%7D" + ) + + print(resp_metricsquery.content) + assert ( + resp_metricsquery.status_code == 200 + ), f"valid query upload 200, but got {resp_metricsquery.status_code} {resp_metricsquery.content}" diff --git a/tests/api-testing/tests/test_organisations.py b/tests/api-testing/tests/test_organisations.py new file mode 100644 index 0000000000..53c2584361 --- /dev/null +++ b/tests/api-testing/tests/test_organisations.py @@ -0,0 +1,58 @@ +def test_e2e_organisations(create_session, base_url): + """Running an E2E test for get all the alerts list.""" + + session = create_session + url = base_url + org_id = "default" + + resp_get_allorgs = session.get(f"{url}api/{org_id}/organizations") + + print(resp_get_allorgs.content) + assert ( + resp_get_allorgs.status_code == 200 + ), f"Get all alerts list 200, but got {resp_get_allorgs.status_code} {resp_get_allorgs.content}" + + +def test_e2e_org_settings(create_session, base_url): + """Running an E2E test for get all the alerts list.""" + + session = create_session + url = base_url + org_id = "default" + + resp_get_orgsettings = session.get(f"{url}api/{org_id}/settings") + + print(resp_get_orgsettings.content) + assert ( + resp_get_orgsettings.status_code == 200 + ), f"Get all alerts list 200, but got {resp_get_orgsettings.status_code} {resp_get_orgsettings.content}" + + +def test_e2e_org_summary(create_session, base_url): + """Running an E2E test for get all the alerts list.""" + + session = create_session + url = base_url + org_id = "default" + + resp_get_orgsummary = session.get(f"{url}api/{org_id}/summary") + + print(resp_get_orgsummary.content) + assert ( + resp_get_orgsummary.status_code == 200 + ), f"Get all alerts list 200, but got {resp_get_orgsummary.status_code} {resp_get_orgsummary.content}" + + +def test_e2e_passcode(create_session, base_url): + """Running an E2E test for get all the alerts list.""" + + session = create_session + url = base_url + org_id = "default" + + resp_get_allorgs = session.get(f"{url}api/{org_id}/organizations/passcode") + + print(resp_get_allorgs.content) + assert ( + resp_get_allorgs.status_code == 200 + ), f"Get all alerts list 200, but got {resp_get_allorgs.status_code} {resp_get_allorgs.content}" diff --git a/tests/api-testing/tests/test_prod.py b/tests/api-testing/tests/test_prod.py new file mode 100644 index 0000000000..8e298d1161 --- /dev/null +++ b/tests/api-testing/tests/test_prod.py @@ -0,0 +1,199 @@ +import requests +import pytest + + +pytestmark = pytest.mark.parametrize( + "base_url", ["https://alpha1-api.dev.zinclabs.dev/"] +) + + +def test_e2e_getusertoken(base_url): + """Running an E2E test for get user token.""" + + if base_url.startswith("https://alpha"): + pytest.skip("alpha1 is unsupported") + headers = { + "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjI0MjAwMTE1NzgwMTY1ODc2OSIsInR5cCI6IkpXVCJ9.eyJhbXIiOlsicGFzc3dvcmQiLCJwd2QiXSwiYXRfaGFzaCI6IjJ3Nnc2UWpZRWRYcUU0c1Q5cGlWUVEiLCJhdWQiOlsiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiMjMxODE2NDA1ODAzMTk3NTYxQG9wZW5vYnNlcnZlIiwiMjMxODE1Njc0NTg0OTQ5ODgxIl0sImF1dGhfdGltZSI6MTcwMDc0MDA2MCwiYXpwIjoiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiY19oYXNoIjoibEJHUm9BZnVTbzJNVWJ0czZSRTBydyIsImNsaWVudF9pZCI6IjIzMTgxNjA2NDkwNjk0NTY1N0BvcGVub2JzZXJ2ZSIsImVtYWlsIjoibmVoYSsxNDQ0MkBvcGVub2JzZXJ2ZS5haSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE3MDA3ODMyNzMsImZhbWlseV9uYW1lIjoidGFya2FzZSIsImdlbmRlciI6Im1hbGUiLCJnaXZlbl9uYW1lIjoib3ZydHR0IiwiaWF0IjoxNzAwNzQwMDYzLCJpc3MiOiJodHRwczovL2FscGhhLXRncWF0YS56aXRhZGVsLmNsb3VkIiwibG9jYWxlIjoiZW4iLCJuYW1lIjoib3ZydHR0IHRhcmthc2UiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJuZWhhKzE0NDQyQG9wZW5vYnNlcnZlLmFpIiwic3ViIjoiMjMzNTc1NDg3ODkxMzM4NjAxIiwidXBkYXRlZF9hdCI6MTY5NTcyNDQxNSwidXJuOnppdGFkZWw6aWFtOm9yZzppZCI6IjIzMTgxNDUyMTkzOTg3OTAzMyIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6aWQiOiIyMzE4MTQ1MjE5Mzk4NzkwMzMiLCJ1cm46eml0YWRlbDppYW06dXNlcjpyZXNvdXJjZW93bmVyOm5hbWUiOiJPcGVuT2JzZXJ2ZSIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6cHJpbWFyeV9kb21haW4iOiJvcGVub2JzZXJ2ZS56aXRhZGVsLmNsb3VkIn0.eFjeY6RhwBk9F1kViVRj4x0h38ie1YGdTurJK7pZ3XbKDgOpymrpAHkyXVvxmwrVETdRDvgGyl0AYFP78gvOP_bOev-2X4HfVQjWKgre004AfAm1rneQ_rIsRkWpT4Oh6SrjXK6WC5QvPJV8319eOGAjSAh0jqPC-3X8e7K3pTyhMlt0LEW69werh-N0BNb3seegwcq4fEFrQsS5JHvVn33mAw8AORRWFFV_yeYL2GdfschVTdz0nLtaY_ksd8-gDo_61sEVKg4nUGS5Fw401h_1wzJpeBvcRmW5OAJvUlSI2ulO8CnfE-Jmy3p3Eod-6AabmsvitEeu02f6P3zAlw" + } + resp_get_rumtoken = requests.get(f"{base_url}api/usertoken", headers=headers) + + # get rumtoken + print(resp_get_rumtoken.content) + assert ( + resp_get_rumtoken.status_code == 200 + ), f"Get usertoken 200, but got {resp_get_rumtoken.status_code} {resp_get_rumtoken.content}" + + +def test_e2e_sendusertokenprod(base_url): + """Running an E2E test for get user token.""" + if base_url.startswith("https://alpha"): + pytest.skip("alpha1 is unsupported") + + headers = { + "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjI0MjAwMTE1NzgwMTY1ODc2OSIsInR5cCI6IkpXVCJ9.eyJhbXIiOlsicGFzc3dvcmQiLCJwd2QiXSwiYXRfaGFzaCI6IjJ3Nnc2UWpZRWRYcUU0c1Q5cGlWUVEiLCJhdWQiOlsiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiMjMxODE2NDA1ODAzMTk3NTYxQG9wZW5vYnNlcnZlIiwiMjMxODE1Njc0NTg0OTQ5ODgxIl0sImF1dGhfdGltZSI6MTcwMDc0MDA2MCwiYXpwIjoiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiY19oYXNoIjoibEJHUm9BZnVTbzJNVWJ0czZSRTBydyIsImNsaWVudF9pZCI6IjIzMTgxNjA2NDkwNjk0NTY1N0BvcGVub2JzZXJ2ZSIsImVtYWlsIjoibmVoYSsxNDQ0MkBvcGVub2JzZXJ2ZS5haSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE3MDA3ODMyNzMsImZhbWlseV9uYW1lIjoidGFya2FzZSIsImdlbmRlciI6Im1hbGUiLCJnaXZlbl9uYW1lIjoib3ZydHR0IiwiaWF0IjoxNzAwNzQwMDYzLCJpc3MiOiJodHRwczovL2FscGhhLXRncWF0YS56aXRhZGVsLmNsb3VkIiwibG9jYWxlIjoiZW4iLCJuYW1lIjoib3ZydHR0IHRhcmthc2UiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJuZWhhKzE0NDQyQG9wZW5vYnNlcnZlLmFpIiwic3ViIjoiMjMzNTc1NDg3ODkxMzM4NjAxIiwidXBkYXRlZF9hdCI6MTY5NTcyNDQxNSwidXJuOnppdGFkZWw6aWFtOm9yZzppZCI6IjIzMTgxNDUyMTkzOTg3OTAzMyIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6aWQiOiIyMzE4MTQ1MjE5Mzk4NzkwMzMiLCJ1cm46eml0YWRlbDppYW06dXNlcjpyZXNvdXJjZW93bmVyOm5hbWUiOiJPcGVuT2JzZXJ2ZSIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6cHJpbWFyeV9kb21haW4iOiJvcGVub2JzZXJ2ZS56aXRhZGVsLmNsb3VkIn0.eFjeY6RhwBk9F1kViVRj4x0h38ie1YGdTurJK7pZ3XbKDgOpymrpAHkyXVvxmwrVETdRDvgGyl0AYFP78gvOP_bOev-2X4HfVQjWKgre004AfAm1rneQ_rIsRkWpT4Oh6SrjXK6WC5QvPJV8319eOGAjSAh0jqPC-3X8e7K3pTyhMlt0LEW69werh-N0BNb3seegwcq4fEFrQsS5JHvVn33mAw8AORRWFFV_yeYL2GdfschVTdz0nLtaY_ksd8-gDo_61sEVKg4nUGS5Fw401h_1wzJpeBvcRmW5OAJvUlSI2ulO8CnfE-Jmy3p3Eod-6AabmsvitEeu02f6P3zAlw" + } + + payload = { + "id": "", + "api_name": "", + "org_identifier": ["ovrttt_organization_62_WnHDzFbSKW0lS79"], + } + + resp_get_usertoken = requests.post( + f"{base_url}api/usertoken", json=payload, headers=headers + ) + + # get rumtoken + print(resp_get_usertoken.content) + assert ( + resp_get_usertoken.status_code == 400 + ), f"Get usertoken 200, but got {resp_get_usertoken.status_code} {resp_get_usertoken.content}" + + +def test_e2e_sendusertoken(base_url): + """Running an E2E test for get user token.""" + if base_url.startswith("https://alpha"): + pytest.skip("alpha1 is unsupported") + + headers = { + "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjI0MjAwMTE1NzgwMTY1ODc2OSIsInR5cCI6IkpXVCJ9.eyJhbXIiOlsicGFzc3dvcmQiLCJwd2QiXSwiYXRfaGFzaCI6IjJ3Nnc2UWpZRWRYcUU0c1Q5cGlWUVEiLCJhdWQiOlsiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiMjMxODE2NDA1ODAzMTk3NTYxQG9wZW5vYnNlcnZlIiwiMjMxODE1Njc0NTg0OTQ5ODgxIl0sImF1dGhfdGltZSI6MTcwMDc0MDA2MCwiYXpwIjoiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiY19oYXNoIjoibEJHUm9BZnVTbzJNVWJ0czZSRTBydyIsImNsaWVudF9pZCI6IjIzMTgxNjA2NDkwNjk0NTY1N0BvcGVub2JzZXJ2ZSIsImVtYWlsIjoibmVoYSsxNDQ0MkBvcGVub2JzZXJ2ZS5haSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE3MDA3ODMyNzMsImZhbWlseV9uYW1lIjoidGFya2FzZSIsImdlbmRlciI6Im1hbGUiLCJnaXZlbl9uYW1lIjoib3ZydHR0IiwiaWF0IjoxNzAwNzQwMDYzLCJpc3MiOiJodHRwczovL2FscGhhLXRncWF0YS56aXRhZGVsLmNsb3VkIiwibG9jYWxlIjoiZW4iLCJuYW1lIjoib3ZydHR0IHRhcmthc2UiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJuZWhhKzE0NDQyQG9wZW5vYnNlcnZlLmFpIiwic3ViIjoiMjMzNTc1NDg3ODkxMzM4NjAxIiwidXBkYXRlZF9hdCI6MTY5NTcyNDQxNSwidXJuOnppdGFkZWw6aWFtOm9yZzppZCI6IjIzMTgxNDUyMTkzOTg3OTAzMyIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6aWQiOiIyMzE4MTQ1MjE5Mzk4NzkwMzMiLCJ1cm46eml0YWRlbDppYW06dXNlcjpyZXNvdXJjZW93bmVyOm5hbWUiOiJPcGVuT2JzZXJ2ZSIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6cHJpbWFyeV9kb21haW4iOiJvcGVub2JzZXJ2ZS56aXRhZGVsLmNsb3VkIn0.eFjeY6RhwBk9F1kViVRj4x0h38ie1YGdTurJK7pZ3XbKDgOpymrpAHkyXVvxmwrVETdRDvgGyl0AYFP78gvOP_bOev-2X4HfVQjWKgre004AfAm1rneQ_rIsRkWpT4Oh6SrjXK6WC5QvPJV8319eOGAjSAh0jqPC-3X8e7K3pTyhMlt0LEW69werh-N0BNb3seegwcq4fEFrQsS5JHvVn33mAw8AORRWFFV_yeYL2GdfschVTdz0nLtaY_ksd8-gDo_61sEVKg4nUGS5Fw401h_1wzJpeBvcRmW5OAJvUlSI2ulO8CnfE-Jmy3p3Eod-6AabmsvitEeu02f6P3zAlw" + } + + payload = { + "id": "", + "api_name": "userkeytest", + "org_identifier": ["ovrttt_organization_62_WnHDzFbSKW0lS79"], + } + + resp_get_usertoken = requests.post( + f"{base_url}api/usertoken", json=payload, headers=headers + ) + + # get rumtoken + print(resp_get_usertoken.content) + assert ( + resp_get_usertoken.status_code == 200 + ), f"Get usertoken 200, but got {resp_get_usertoken.status_code} {resp_get_usertoken.content}" + + +def test_e2e_useremail(base_url): + """Running an E2E test for get user token.""" + if base_url.startswith("https://alpha"): + pytest.skip("alpha1 is unsupported") + + headers = { + "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjI0MjAwMTE1NzgwMTY1ODc2OSIsInR5cCI6IkpXVCJ9.eyJhbXIiOlsicGFzc3dvcmQiLCJwd2QiXSwiYXRfaGFzaCI6IjJ3Nnc2UWpZRWRYcUU0c1Q5cGlWUVEiLCJhdWQiOlsiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiMjMxODE2NDA1ODAzMTk3NTYxQG9wZW5vYnNlcnZlIiwiMjMxODE1Njc0NTg0OTQ5ODgxIl0sImF1dGhfdGltZSI6MTcwMDc0MDA2MCwiYXpwIjoiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiY19oYXNoIjoibEJHUm9BZnVTbzJNVWJ0czZSRTBydyIsImNsaWVudF9pZCI6IjIzMTgxNjA2NDkwNjk0NTY1N0BvcGVub2JzZXJ2ZSIsImVtYWlsIjoibmVoYSsxNDQ0MkBvcGVub2JzZXJ2ZS5haSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE3MDA3ODMyNzMsImZhbWlseV9uYW1lIjoidGFya2FzZSIsImdlbmRlciI6Im1hbGUiLCJnaXZlbl9uYW1lIjoib3ZydHR0IiwiaWF0IjoxNzAwNzQwMDYzLCJpc3MiOiJodHRwczovL2FscGhhLXRncWF0YS56aXRhZGVsLmNsb3VkIiwibG9jYWxlIjoiZW4iLCJuYW1lIjoib3ZydHR0IHRhcmthc2UiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJuZWhhKzE0NDQyQG9wZW5vYnNlcnZlLmFpIiwic3ViIjoiMjMzNTc1NDg3ODkxMzM4NjAxIiwidXBkYXRlZF9hdCI6MTY5NTcyNDQxNSwidXJuOnppdGFkZWw6aWFtOm9yZzppZCI6IjIzMTgxNDUyMTkzOTg3OTAzMyIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6aWQiOiIyMzE4MTQ1MjE5Mzk4NzkwMzMiLCJ1cm46eml0YWRlbDppYW06dXNlcjpyZXNvdXJjZW93bmVyOm5hbWUiOiJPcGVuT2JzZXJ2ZSIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6cHJpbWFyeV9kb21haW4iOiJvcGVub2JzZXJ2ZS56aXRhZGVsLmNsb3VkIn0.eFjeY6RhwBk9F1kViVRj4x0h38ie1YGdTurJK7pZ3XbKDgOpymrpAHkyXVvxmwrVETdRDvgGyl0AYFP78gvOP_bOev-2X4HfVQjWKgre004AfAm1rneQ_rIsRkWpT4Oh6SrjXK6WC5QvPJV8319eOGAjSAh0jqPC-3X8e7K3pTyhMlt0LEW69werh-N0BNb3seegwcq4fEFrQsS5JHvVn33mAw8AORRWFFV_yeYL2GdfschVTdz0nLtaY_ksd8-gDo_61sEVKg4nUGS5Fw401h_1wzJpeBvcRmW5OAJvUlSI2ulO8CnfE-Jmy3p3Eod-6AabmsvitEeu02f6P3zAlw" + } + resp_get_rumtoken = requests.get( + f"{base_url}api/users/verifyuser/neha+14442@openobserve.ai", headers=headers + ) + + # get rumtoken + print(resp_get_rumtoken.content) + assert ( + resp_get_rumtoken.status_code == 200 + ), f"Get usertoken 200, but got {resp_get_rumtoken.status_code} {resp_get_rumtoken.content}" + + +def test_e2e_userinvalidemail(base_url): + """Running an E2E test for get user token.""" + if base_url.startswith("https://alpha"): + pytest.skip("alpha1 is unsupported") + + headers = { + "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjI0MjAwMTE1NzgwMTY1ODc2OSIsInR5cCI6IkpXVCJ9.eyJhbXIiOlsicGFzc3dvcmQiLCJwd2QiXSwiYXRfaGFzaCI6IjJ3Nnc2UWpZRWRYcUU0c1Q5cGlWUVEiLCJhdWQiOlsiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiMjMxODE2NDA1ODAzMTk3NTYxQG9wZW5vYnNlcnZlIiwiMjMxODE1Njc0NTg0OTQ5ODgxIl0sImF1dGhfdGltZSI6MTcwMDc0MDA2MCwiYXpwIjoiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiY19oYXNoIjoibEJHUm9BZnVTbzJNVWJ0czZSRTBydyIsImNsaWVudF9pZCI6IjIzMTgxNjA2NDkwNjk0NTY1N0BvcGVub2JzZXJ2ZSIsImVtYWlsIjoibmVoYSsxNDQ0MkBvcGVub2JzZXJ2ZS5haSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE3MDA3ODMyNzMsImZhbWlseV9uYW1lIjoidGFya2FzZSIsImdlbmRlciI6Im1hbGUiLCJnaXZlbl9uYW1lIjoib3ZydHR0IiwiaWF0IjoxNzAwNzQwMDYzLCJpc3MiOiJodHRwczovL2FscGhhLXRncWF0YS56aXRhZGVsLmNsb3VkIiwibG9jYWxlIjoiZW4iLCJuYW1lIjoib3ZydHR0IHRhcmthc2UiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJuZWhhKzE0NDQyQG9wZW5vYnNlcnZlLmFpIiwic3ViIjoiMjMzNTc1NDg3ODkxMzM4NjAxIiwidXBkYXRlZF9hdCI6MTY5NTcyNDQxNSwidXJuOnppdGFkZWw6aWFtOm9yZzppZCI6IjIzMTgxNDUyMTkzOTg3OTAzMyIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6aWQiOiIyMzE4MTQ1MjE5Mzk4NzkwMzMiLCJ1cm46eml0YWRlbDppYW06dXNlcjpyZXNvdXJjZW93bmVyOm5hbWUiOiJPcGVuT2JzZXJ2ZSIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6cHJpbWFyeV9kb21haW4iOiJvcGVub2JzZXJ2ZS56aXRhZGVsLmNsb3VkIn0.eFjeY6RhwBk9F1kViVRj4x0h38ie1YGdTurJK7pZ3XbKDgOpymrpAHkyXVvxmwrVETdRDvgGyl0AYFP78gvOP_bOev-2X4HfVQjWKgre004AfAm1rneQ_rIsRkWpT4Oh6SrjXK6WC5QvPJV8319eOGAjSAh0jqPC-3X8e7K3pTyhMlt0LEW69werh-N0BNb3seegwcq4fEFrQsS5JHvVn33mAw8AORRWFFV_yeYL2GdfschVTdz0nLtaY_ksd8-gDo_61sEVKg4nUGS5Fw401h_1wzJpeBvcRmW5OAJvUlSI2ulO8CnfE-Jmy3p3Eod-6AabmsvitEeu02f6P3zAlw" + } + resp_get_rumtoken = requests.get( + f"{base_url}api/users/verifyuser/neha+1", headers=headers + ) + + # get rumtoken + print(resp_get_rumtoken.content) + assert ( + resp_get_rumtoken.status_code == 400 + ), f"Get usertoken 400, but got {resp_get_rumtoken.status_code} {resp_get_rumtoken.content}" + + +def test_e2e_userinviteemail(base_url): + """Running an E2E test for get user token.""" + if base_url.startswith("https://alpha"): + pytest.skip("alpha1 is unsupported") + + headers = { + "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjI0MjAwMTE1NzgwMTY1ODc2OSIsInR5cCI6IkpXVCJ9.eyJhbXIiOlsicGFzc3dvcmQiLCJwd2QiXSwiYXRfaGFzaCI6IjJ3Nnc2UWpZRWRYcUU0c1Q5cGlWUVEiLCJhdWQiOlsiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiMjMxODE2NDA1ODAzMTk3NTYxQG9wZW5vYnNlcnZlIiwiMjMxODE1Njc0NTg0OTQ5ODgxIl0sImF1dGhfdGltZSI6MTcwMDc0MDA2MCwiYXpwIjoiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiY19oYXNoIjoibEJHUm9BZnVTbzJNVWJ0czZSRTBydyIsImNsaWVudF9pZCI6IjIzMTgxNjA2NDkwNjk0NTY1N0BvcGVub2JzZXJ2ZSIsImVtYWlsIjoibmVoYSsxNDQ0MkBvcGVub2JzZXJ2ZS5haSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE3MDA3ODMyNzMsImZhbWlseV9uYW1lIjoidGFya2FzZSIsImdlbmRlciI6Im1hbGUiLCJnaXZlbl9uYW1lIjoib3ZydHR0IiwiaWF0IjoxNzAwNzQwMDYzLCJpc3MiOiJodHRwczovL2FscGhhLXRncWF0YS56aXRhZGVsLmNsb3VkIiwibG9jYWxlIjoiZW4iLCJuYW1lIjoib3ZydHR0IHRhcmthc2UiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJuZWhhKzE0NDQyQG9wZW5vYnNlcnZlLmFpIiwic3ViIjoiMjMzNTc1NDg3ODkxMzM4NjAxIiwidXBkYXRlZF9hdCI6MTY5NTcyNDQxNSwidXJuOnppdGFkZWw6aWFtOm9yZzppZCI6IjIzMTgxNDUyMTkzOTg3OTAzMyIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6aWQiOiIyMzE4MTQ1MjE5Mzk4NzkwMzMiLCJ1cm46eml0YWRlbDppYW06dXNlcjpyZXNvdXJjZW93bmVyOm5hbWUiOiJPcGVuT2JzZXJ2ZSIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6cHJpbWFyeV9kb21haW4iOiJvcGVub2JzZXJ2ZS56aXRhZGVsLmNsb3VkIn0.eFjeY6RhwBk9F1kViVRj4x0h38ie1YGdTurJK7pZ3XbKDgOpymrpAHkyXVvxmwrVETdRDvgGyl0AYFP78gvOP_bOev-2X4HfVQjWKgre004AfAm1rneQ_rIsRkWpT4Oh6SrjXK6WC5QvPJV8319eOGAjSAh0jqPC-3X8e7K3pTyhMlt0LEW69werh-N0BNb3seegwcq4fEFrQsS5JHvVn33mAw8AORRWFFV_yeYL2GdfschVTdz0nLtaY_ksd8-gDo_61sEVKg4nUGS5Fw401h_1wzJpeBvcRmW5OAJvUlSI2ulO8CnfE-Jmy3p3Eod-6AabmsvitEeu02f6P3zAlw" + } + resp_get_rumtoken = requests.get( + f"{base_url}api/organizations/member_subscription/wrongemail", headers=headers + ) + + # get rumtoken + print(resp_get_rumtoken.content) + assert ( + resp_get_rumtoken.status_code == 400 + ), f"Get usertoken 400, but got {resp_get_rumtoken.status_code} {resp_get_rumtoken.content}" + + +def test_e2e_userinvitevalidemail(base_url): + """Running an E2E test for get user token.""" + + if base_url.startswith("https://alpha"): + pytest.skip("alpha1 is unsupported") + headers = { + "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjI0MjAwMTE1NzgwMTY1ODc2OSIsInR5cCI6IkpXVCJ9.eyJhbXIiOlsicGFzc3dvcmQiLCJwd2QiXSwiYXRfaGFzaCI6IjJ3Nnc2UWpZRWRYcUU0c1Q5cGlWUVEiLCJhdWQiOlsiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiMjMxODE2NDA1ODAzMTk3NTYxQG9wZW5vYnNlcnZlIiwiMjMxODE1Njc0NTg0OTQ5ODgxIl0sImF1dGhfdGltZSI6MTcwMDc0MDA2MCwiYXpwIjoiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiY19oYXNoIjoibEJHUm9BZnVTbzJNVWJ0czZSRTBydyIsImNsaWVudF9pZCI6IjIzMTgxNjA2NDkwNjk0NTY1N0BvcGVub2JzZXJ2ZSIsImVtYWlsIjoibmVoYSsxNDQ0MkBvcGVub2JzZXJ2ZS5haSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE3MDA3ODMyNzMsImZhbWlseV9uYW1lIjoidGFya2FzZSIsImdlbmRlciI6Im1hbGUiLCJnaXZlbl9uYW1lIjoib3ZydHR0IiwiaWF0IjoxNzAwNzQwMDYzLCJpc3MiOiJodHRwczovL2FscGhhLXRncWF0YS56aXRhZGVsLmNsb3VkIiwibG9jYWxlIjoiZW4iLCJuYW1lIjoib3ZydHR0IHRhcmthc2UiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJuZWhhKzE0NDQyQG9wZW5vYnNlcnZlLmFpIiwic3ViIjoiMjMzNTc1NDg3ODkxMzM4NjAxIiwidXBkYXRlZF9hdCI6MTY5NTcyNDQxNSwidXJuOnppdGFkZWw6aWFtOm9yZzppZCI6IjIzMTgxNDUyMTkzOTg3OTAzMyIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6aWQiOiIyMzE4MTQ1MjE5Mzk4NzkwMzMiLCJ1cm46eml0YWRlbDppYW06dXNlcjpyZXNvdXJjZW93bmVyOm5hbWUiOiJPcGVuT2JzZXJ2ZSIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6cHJpbWFyeV9kb21haW4iOiJvcGVub2JzZXJ2ZS56aXRhZGVsLmNsb3VkIn0.eFjeY6RhwBk9F1kViVRj4x0h38ie1YGdTurJK7pZ3XbKDgOpymrpAHkyXVvxmwrVETdRDvgGyl0AYFP78gvOP_bOev-2X4HfVQjWKgre004AfAm1rneQ_rIsRkWpT4Oh6SrjXK6WC5QvPJV8319eOGAjSAh0jqPC-3X8e7K3pTyhMlt0LEW69werh-N0BNb3seegwcq4fEFrQsS5JHvVn33mAw8AORRWFFV_yeYL2GdfschVTdz0nLtaY_ksd8-gDo_61sEVKg4nUGS5Fw401h_1wzJpeBvcRmW5OAJvUlSI2ulO8CnfE-Jmy3p3Eod-6AabmsvitEeu02f6P3zAlw" + } + payload = {"member_lists": ["nehapawar@g.com"], "role": "admin"} + resp_get_rumtoken = requests.post( + f"{base_url}api/ovrttt_organization_62_WnHDzFbSKW0lS79/organizations/members", + json=payload, + headers=headers, + ) + + # get rumtoken + print(resp_get_rumtoken.content) + assert ( + resp_get_rumtoken.status_code == 200 + ), f"Get usertoken 200, but got {resp_get_rumtoken.status_code} {resp_get_rumtoken.content}" + + +def test_e2e_userinvitenovalidemail(base_url): + """Running an E2E test for get user token.""" + if base_url.startswith("https://alpha"): + pytest.skip("alpha1 is unsupported") + + headers = { + "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjI0MjAwMTE1NzgwMTY1ODc2OSIsInR5cCI6IkpXVCJ9.eyJhbXIiOlsicGFzc3dvcmQiLCJwd2QiXSwiYXRfaGFzaCI6IjJ3Nnc2UWpZRWRYcUU0c1Q5cGlWUVEiLCJhdWQiOlsiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiMjMxODE2NDA1ODAzMTk3NTYxQG9wZW5vYnNlcnZlIiwiMjMxODE1Njc0NTg0OTQ5ODgxIl0sImF1dGhfdGltZSI6MTcwMDc0MDA2MCwiYXpwIjoiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiY19oYXNoIjoibEJHUm9BZnVTbzJNVWJ0czZSRTBydyIsImNsaWVudF9pZCI6IjIzMTgxNjA2NDkwNjk0NTY1N0BvcGVub2JzZXJ2ZSIsImVtYWlsIjoibmVoYSsxNDQ0MkBvcGVub2JzZXJ2ZS5haSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE3MDA3ODMyNzMsImZhbWlseV9uYW1lIjoidGFya2FzZSIsImdlbmRlciI6Im1hbGUiLCJnaXZlbl9uYW1lIjoib3ZydHR0IiwiaWF0IjoxNzAwNzQwMDYzLCJpc3MiOiJodHRwczovL2FscGhhLXRncWF0YS56aXRhZGVsLmNsb3VkIiwibG9jYWxlIjoiZW4iLCJuYW1lIjoib3ZydHR0IHRhcmthc2UiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJuZWhhKzE0NDQyQG9wZW5vYnNlcnZlLmFpIiwic3ViIjoiMjMzNTc1NDg3ODkxMzM4NjAxIiwidXBkYXRlZF9hdCI6MTY5NTcyNDQxNSwidXJuOnppdGFkZWw6aWFtOm9yZzppZCI6IjIzMTgxNDUyMTkzOTg3OTAzMyIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6aWQiOiIyMzE4MTQ1MjE5Mzk4NzkwMzMiLCJ1cm46eml0YWRlbDppYW06dXNlcjpyZXNvdXJjZW93bmVyOm5hbWUiOiJPcGVuT2JzZXJ2ZSIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6cHJpbWFyeV9kb21haW4iOiJvcGVub2JzZXJ2ZS56aXRhZGVsLmNsb3VkIn0.eFjeY6RhwBk9F1kViVRj4x0h38ie1YGdTurJK7pZ3XbKDgOpymrpAHkyXVvxmwrVETdRDvgGyl0AYFP78gvOP_bOev-2X4HfVQjWKgre004AfAm1rneQ_rIsRkWpT4Oh6SrjXK6WC5QvPJV8319eOGAjSAh0jqPC-3X8e7K3pTyhMlt0LEW69werh-N0BNb3seegwcq4fEFrQsS5JHvVn33mAw8AORRWFFV_yeYL2GdfschVTdz0nLtaY_ksd8-gDo_61sEVKg4nUGS5Fw401h_1wzJpeBvcRmW5OAJvUlSI2ulO8CnfE-Jmy3p3Eod-6AabmsvitEeu02f6P3zAlw" + } + payload = {"member_lists": ["donotadd"], "role": "admin"} + resp_get_rumtoken = requests.post( + f"{base_url}api/ovrttt_organization_62_WnHDzFbSKW0lS79/organizations/members", + json=payload, + headers=headers, + ) + + # get rumtoken + print(resp_get_rumtoken.content) + assert ( + resp_get_rumtoken.status_code == 200 + ), f"Get usertoken 200, but got {resp_get_rumtoken.status_code} {resp_get_rumtoken.content}" + + +def test_e2e_userinviteinvalidemail(base_url): + """Running an E2E test for get user token.""" + if base_url.startswith("https://alpha"): + pytest.skip("alpha1 is unsupported") + + headers = { + "Authorization": "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjI0MjAwMTE1NzgwMTY1ODc2OSIsInR5cCI6IkpXVCJ9.eyJhbXIiOlsicGFzc3dvcmQiLCJwd2QiXSwiYXRfaGFzaCI6IjJ3Nnc2UWpZRWRYcUU0c1Q5cGlWUVEiLCJhdWQiOlsiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiMjMxODE2NDA1ODAzMTk3NTYxQG9wZW5vYnNlcnZlIiwiMjMxODE1Njc0NTg0OTQ5ODgxIl0sImF1dGhfdGltZSI6MTcwMDc0MDA2MCwiYXpwIjoiMjMxODE2MDY0OTA2OTQ1NjU3QG9wZW5vYnNlcnZlIiwiY19oYXNoIjoibEJHUm9BZnVTbzJNVWJ0czZSRTBydyIsImNsaWVudF9pZCI6IjIzMTgxNjA2NDkwNjk0NTY1N0BvcGVub2JzZXJ2ZSIsImVtYWlsIjoibmVoYSsxNDQ0MkBvcGVub2JzZXJ2ZS5haSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE3MDA3ODMyNzMsImZhbWlseV9uYW1lIjoidGFya2FzZSIsImdlbmRlciI6Im1hbGUiLCJnaXZlbl9uYW1lIjoib3ZydHR0IiwiaWF0IjoxNzAwNzQwMDYzLCJpc3MiOiJodHRwczovL2FscGhhLXRncWF0YS56aXRhZGVsLmNsb3VkIiwibG9jYWxlIjoiZW4iLCJuYW1lIjoib3ZydHR0IHRhcmthc2UiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJuZWhhKzE0NDQyQG9wZW5vYnNlcnZlLmFpIiwic3ViIjoiMjMzNTc1NDg3ODkxMzM4NjAxIiwidXBkYXRlZF9hdCI6MTY5NTcyNDQxNSwidXJuOnppdGFkZWw6aWFtOm9yZzppZCI6IjIzMTgxNDUyMTkzOTg3OTAzMyIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6aWQiOiIyMzE4MTQ1MjE5Mzk4NzkwMzMiLCJ1cm46eml0YWRlbDppYW06dXNlcjpyZXNvdXJjZW93bmVyOm5hbWUiOiJPcGVuT2JzZXJ2ZSIsInVybjp6aXRhZGVsOmlhbTp1c2VyOnJlc291cmNlb3duZXI6cHJpbWFyeV9kb21haW4iOiJvcGVub2JzZXJ2ZS56aXRhZGVsLmNsb3VkIn0.eFjeY6RhwBk9F1kViVRj4x0h38ie1YGdTurJK7pZ3XbKDgOpymrpAHkyXVvxmwrVETdRDvgGyl0AYFP78gvOP_bOev-2X4HfVQjWKgre004AfAm1rneQ_rIsRkWpT4Oh6SrjXK6WC5QvPJV8319eOGAjSAh0jqPC-3X8e7K3pTyhMlt0LEW69werh-N0BNb3seegwcq4fEFrQsS5JHvVn33mAw8AORRWFFV_yeYL2GdfschVTdz0nLtaY_ksd8-gDo_61sEVKg4nUGS5Fw401h_1wzJpeBvcRmW5OAJvUlSI2ulO8CnfE-Jmy3p3Eod-6AabmsvitEeu02f6P3zAlw" + } + payload = {"member_lists": ["aaW @@@@g.com"], "role": "admin"} + resp_get_rumtoken = requests.post( + f"{base_url}api/ovrttt_organization_62_WnHDzFbSKW0lS79/organizations/members", + json=payload, + headers=headers, + ) + + # get rumtoken + print(resp_get_rumtoken.content) + assert ( + resp_get_rumtoken.status_code == 200 + ), f"Get usertoken 200, but got {resp_get_rumtoken.status_code} {resp_get_rumtoken.content}" diff --git a/tests/api-testing/tests/test_rum.py b/tests/api-testing/tests/test_rum.py new file mode 100644 index 0000000000..a92c91964e --- /dev/null +++ b/tests/api-testing/tests/test_rum.py @@ -0,0 +1,410 @@ +import json +import requests +import uuid +from datetime import datetime, timezone, timedelta +import time + + +def parse_json(input_str): + return json.loads(input_str) + + +def test_e2e_rumtoken(create_session, base_url): + """Running an E2E test for get rum token.""" + + session = create_session + org_id = "default" + + resp_get_rumtoken = session.get(f"{base_url}api/{org_id}/organizations/rumtoken") + + # get rumtoken + print(resp_get_rumtoken.content) + assert ( + resp_get_rumtoken.status_code == 200 + ), f"Get all functions list 200, but got {resp_get_rumtoken.status_code} {resp_get_rumtoken.content}" + + +def test_e2e_invalidrumtoken(create_session, base_url): + """Running an E2E test for get rum token.""" + + rum_org = "e2e" + logs_url = f"{base_url}rum/v1/{rum_org}/logs" + rum_api_token = "rumxJwgUyIx3U" + params = { + "oosource": "browser", + "ootags": "sdk_version:0.2.7,api:fetch,env:production,service:my-web-application,version:0.0.1", + "oo-api-key": rum_api_token, + "oo-request-id": "44004cf7-7149-4d9d-8e43-ca238d8afbe8", + "oo-evp-origin": "browser", + } + unique_test_identifier = f"pytest-{uuid.uuid4()}" + print(unique_test_identifier) + + logs_payload = """{"service":""}""" + logs_payload_json = parse_json(logs_payload) + logs_payload_json["message"] = unique_test_identifier + + resp_post_rum_logs = requests.post(logs_url, params=params, json=logs_payload_json) + expected = 403 + got = resp_post_rum_logs.status_code + + assert ( + expected == got + ), f"Failed to post to rum-logs, expected={expected} got={got}, {resp_post_rum_logs.content}" + + +def test_e2e_rumdataingestioninvalidtoken(create_session, base_url): + """Running an E2E test for rum data with invalid rum token.""" + + session = create_session + rum_org = "e2e" + rumdata_url = f"{base_url}rum/v1/{rum_org}/rum" + rum_api_token = "rumv7T" + params = { + "oosource": "browser", + "ootags": "sdk_version:0.2.7,api:fetch,env:production,service:my-web-application,version:0.0.1", + "oo-api-key": rum_api_token, + "oo-request-id": "44004cf7-7149-4d9d-8e43-ca238d8afbe8", + "oo-evp-origin": "browser", + } + unique_test_identifier = f"pytest-{uuid.uuid4()}" + print(unique_test_identifier) + + rumdata_payload = """{"_oo":{"format_version":2,"drift":0,"session":{"plan":2},"configuration":{"session_sample_rate":100,"session_replay_sample_rate":100},"discarded":false},"application":{"id":"1"},"date":1698048457936,"service":"my-web-application","version":"0.0.1","source":"browser","session":{"id":"30e6488a-3c60-4ffa-8549-468da66f6512","type":"user"},"view":{"id":"105d0f30-ea01-4cd9-96ff-dfbbafd8f7c3","url":"http://127.0.0.1:5173/","referrer":""},"display":{"viewport":{"width":1920,"height":941}},"resource":{"id":"42c413d1-2863-45ce-830c-68a3699ca98f","type":"image","url":"http://127.0.0.1:5173/src/assets/logo.svg?import","duration":16900000,"size":37,"download":{"duration":3200000,"start":13700000},"first_byte":{"duration":2800000,"start":10900000},"connect":{"duration":0,"start":10700000},"dns":{"duration":100000,"start":10600000}},"type":"resource"}""" + rumdata_payload_json = parse_json(rumdata_payload) + rumdata_payload_json["type"] = unique_test_identifier + + resp_post_rumdata = session.post( + rumdata_url, params=params, json=rumdata_payload_json + ) + expected = 403 + got = resp_post_rumdata.status_code + + assert ( + expected == got + ), f"Failed to post to rum-data, expected={expected} got={got}, {resp_post_rumdata.content}" + print(resp_post_rumdata) + + +def test_e2e_rumingestinglogs(create_session, base_url): + """Running an E2E test for ingest rum logs.""" + session = create_session + rum_org = "default" + logs_url = f"{base_url}rum/v1/{rum_org}/logs" + ip_address = "182.70.14.246" + resp_get_rumtoken = session.get(f"{base_url}api/{rum_org}/organizations/rumtoken") + + # get rumtoken + print(resp_get_rumtoken.content) + assert ( + resp_get_rumtoken.status_code == 200 + ), f"Get all functions list 200, but got {resp_get_rumtoken.status_code} {resp_get_rumtoken.content}" + + rum_api_token = resp_get_rumtoken.json()["data"]["rum_token"] + + # session = create_session + # rum_org = "default" + # logs_url = f"{base_url}rum/v1/{rum_org}/logs" + # rum_api_token = "rumv7Tjj3SNoF5k9R3A" + params = { + "oosource": "browser", + "ootags": "sdk_version:0.2.7,api:fetch,env:production,service:my-web-application,version:0.0.1", + "oo-api-key": rum_api_token, + "oo-request-id": "44004cf7-7149-4d9d-8e43-ca238d8afbe8", + "oo-evp-origin": "browser", + } + unique_test_identifier = f"pytest-{uuid.uuid4()}" + print(unique_test_identifier) + + logs_payload = """{"service":"my-web-application","session_id":"30e6488a-3c60-4ffa-8549-468da66f6512","view":{"referrer":"http://127.0.0.1:5173/about","url":"http://127.0.0.1:5173/about","id":"5a6c4bc6-f0cb-49ec-b4fb-460eda745efe"},"application_id":"1","date":1698049336226,"message":"what is happening???","origin":"console","status":"info"}""" + logs_payload_json = parse_json(logs_payload) + logs_payload_json["message"] = unique_test_identifier + + ip_headers = {"X-Forwarded-For": ip_address} + resp_post_rum_logs = requests.post( + logs_url, params=params, json=logs_payload_json, headers=ip_headers + ) + expected = 200 + got = resp_post_rum_logs.status_code + + assert ( + expected == got + ), f"Failed to post to rum-logs, expected={expected} got={got}, {resp_post_rum_logs.content}" + + retries = 3 + while True: + try: + params = { + "type": "logs", + } + + now = datetime.now(timezone.utc) + end_time = int(now.timestamp() * 1000000) + five_min_ago = int((now - timedelta(minutes=5)).timestamp() * 1000000) + + json_data = { + "query": { + "sql": 'select * from "_rumlog" order by _timestamp desc limit 5 ;', + "start_time": five_min_ago, + "end_time": end_time, + "from": 0, + "size": 150, + "sql_mode": "full", + }, + } + + search_url = f"{base_url}api/{rum_org}/_search" + response_rum_data = session.post(search_url, params=params, json=json_data) + + # First check if the response is 200. + got = response_rum_data.status_code + expected = 200 + assert ( + expected == got + ), f"Failed to retrieve rum-logs, got = {got}, expected = {expected}, {response_rum_data.content}" + + response_payload = response_rum_data.json() + assert ( + len(response_payload["hits"]) > 0 + ), f"No data found, {response_rum_data.content}" + + response_payload = response_rum_data.json() + assert ( + len(response_payload["hits"]) > 0 + ), f"Failed to retrieve the rum-log, {response_rum_data.content}" + assert ( + response_payload["hits"][0]["message"] == unique_test_identifier + ), f"Failed to retrieve the rum-log, {response_rum_data.content}" + break + except Exception as e: + if retries > 0: + retries -= 1 + time.sleep(3) + print("retrying - exception was ", e) + continue + else: + raise e + + +# This case would never fail, since it is a token generation. +# def test_e2e_generaterumtoken(create_session,base_url): +# """Running an E2E test for get rum token.""" + +# session = create_session +# url = base_url +# org_id = "e2e" +# resp_generate_rumtoken = session.post(f"{base_url}api/{org_id}/organizations/rumtoken") +# print(resp_generate_rumtoken.content) +# rum_token = resp_generate_rumtoken.json()["data"]["rum_token"] + +# #get rumtoken +# print(resp_generate_rumtoken.content) +# assert resp_generate_rumtoken.status_code == 200, f"Get all functions list 200, but got {resp_generate_rumtoken.status_code} {resp_generate_rumtoken.content}" + +# def test_e2e_updaterumtoken(create_session,base_url): +# """Running an E2E test for get rum token.""" + +# session = create_session +# url = base_url +# org_id = "e2e" +# resp_update_rumtoken = session.put(f"{base_url}api/{org_id}/organizations/rumtoken") +# print(resp_update_rumtoken.content) +# rum_token = resp_update_rumtoken.json()["data"]["rum_token"] + +# #get rumtoken +# print(resp_update_rumtoken.content) +# assert resp_update_rumtoken.status_code == 200, f"Get all functions list 200, but got {resp_update_rumtoken.status_code} {resp_update_rumtoken.content}" + +# Ingesting rum data and using search query to validate if data ingested is correct + + +def test_e2e_rumdataingestandsearch(create_session, base_url): + """Running an E2E test for rum data ingest.""" + session = create_session + rum_org = "default" + ip_address = "182.70.14.246" + headers = {"X-Forwarded-For": ip_address, "Content-Type": "application/json"} + resp_get_rumtoken = session.get(f"{base_url}api/{rum_org}/organizations/rumtoken") + + # get rumtoken + print(resp_get_rumtoken.content) + assert ( + resp_get_rumtoken.status_code == 200 + ), f"Get all functions list 200, but got {resp_get_rumtoken.status_code} {resp_get_rumtoken.content}" + + rum_api_token = resp_get_rumtoken.json()["data"]["rum_token"] + rumdata_url = f"{base_url}rum/v1/{rum_org}/rum" + params = { + "oosource": "browser", + "ootags": "sdk_version:0.2.7,api:fetch,env:production,service:my-web-application,version:0.0.1", + "oo-api-key": rum_api_token, + "oo-request-id": "44004cf7-7149-4d9d-8e43-ca238d8afbe8", + "oo-evp-origin": "browser", + } + unique_test_identifier = f"pytest-{uuid.uuid4()}" + print(unique_test_identifier) + + rumdata_payload = """{"_oo":{"format_version":2,"drift":0,"session":{"plan":2},"configuration":{"session_sample_rate":100,"session_replay_sample_rate":100},"discarded":false},"application":{"id":"1"},"date":1698048457936,"service":"my-web-application","version":"0.0.1","source":"browser","session":{"id":"30e6488a-3c60-4ffa-8549-468da66f6512","type":"user"},"view":{"id":"105d0f30-ea01-4cd9-96ff-dfbbafd8f7c3","url":"http://127.0.0.1:5173/","referrer":""},"display":{"viewport":{"width":1920,"height":941}},"resource":{"id":"42c413d1-2863-45ce-830c-68a3699ca98f","type":"image","url":"http://127.0.0.1:5173/src/assets/logo.svg?import","duration":16900000,"size":37,"download":{"duration":3200000,"start":13700000},"first_byte":{"duration":2800000,"start":10900000},"connect":{"duration":0,"start":10700000},"dns":{"duration":100000,"start":10600000}},"type":"resource"}""" + rumdata_payload_json = parse_json(rumdata_payload) + rumdata_payload_json["type"] = unique_test_identifier + + resp_post_rumdata = session.post( + rumdata_url, params=params, json=rumdata_payload_json, headers=headers + ) + expected = 200 + got = resp_post_rumdata.status_code + + assert ( + expected == got + ), f"Failed to post to rum-data, expected={expected} got={got}, {resp_post_rumdata.content}" + print(resp_post_rumdata) + + retries = 3 + while True: + try: + params = { + "type": "logs", + } + + now = datetime.now(timezone.utc) + end_time = int(now.timestamp() * 1000000) + five_min_ago = int((now - timedelta(minutes=5)).timestamp() * 1000000) + + json_data = { + "query": { + "sql": 'select * from "_rumdata" order by _timestamp desc limit 5 ;', + "start_time": five_min_ago, + "end_time": end_time, + "from": 0, + "size": 150, + "sql_mode": "full", + }, + } + + search_url = f"{base_url}api/{rum_org}/_search" + response_rum_data = session.post(search_url, params=params, json=json_data) + + # First check if the response is 200. + got = response_rum_data.status_code + expected = 200 + assert ( + expected == got + ), f"Failed to retrieve rum-data, got = {got}, expected = {expected}, {response_rum_data.content}" + + response_payload = response_rum_data.json() + assert ( + len(response_payload["hits"]) > 0 + ), f"No data found, {response_rum_data.content}" + + assert unique_test_identifier in set( + [payload["type"] for payload in response_payload["hits"]] + ), f"Failed to retrieve the rum-log, {response_rum_data.content}" + break + except Exception as e: + if retries > 0: + retries -= 1 + time.sleep(3) + print("retrying - exception was ", e) + continue + else: + raise e + + +# verify data under rum logs has geo location +def test_e2e_rumverifygeodata(create_session, base_url): + """Running an E2E test for geo data under response.""" + session = create_session + rum_org = "default" + logs_url = f"{base_url}rum/v1/{rum_org}/logs" + ip_address = "182.70.14.246" + headers = {"X-Forwarded-For": ip_address, "Content-Type": "application/json"} + resp_get_rumtoken = session.get(f"{base_url}api/{rum_org}/organizations/rumtoken") + + # get rumtoken + print(resp_get_rumtoken.content) + assert ( + resp_get_rumtoken.status_code == 200 + ), f"Get all functions list 200, but got {resp_get_rumtoken.status_code} {resp_get_rumtoken.content}" + + rum_api_token = resp_get_rumtoken.json()["data"]["rum_token"] + + params = { + "oosource": "browser", + "ootags": "sdk_version:0.2.7,api:fetch,env:production,service:my-web-application,version:0.0.1", + "oo-api-key": rum_api_token, + "oo-request-id": "44004cf7-7149-4d9d-8e43-ca238d8afbe8", + "oo-evp-origin": "browser", + } + unique_test_identifier = f"pytest-{uuid.uuid4()}" + print(unique_test_identifier) + + logs_payload = """{"service":"my-web-application","session_id":"30e6488a-3c60-4ffa-8549-468da66f6512","view":{"referrer":"http://127.0.0.1:5173/about","url":"http://127.0.0.1:5173/about","id":"5a6c4bc6-f0cb-49ec-b4fb-460eda745efe"},"application_id":"1","date":1698049336226,"message":"what is happening???","origin":"console","status":"info"}""" + logs_payload_json = parse_json(logs_payload) + logs_payload_json["message"] = unique_test_identifier + time.sleep(3) + + resp_post_rum_logs = requests.post( + logs_url, params=params, json=logs_payload_json, headers=headers + ) + expected = 200 + got = resp_post_rum_logs.status_code + + assert ( + expected == got + ), f"Failed to post to rum-logs, expected={expected} got={got}, {resp_post_rum_logs.content}" + + retries = 3 + while True: + try: + params = { + "type": "logs", + } + + now = datetime.now(timezone.utc) + end_time = int(now.timestamp() * 1000000) + one_min_ago = int((now - timedelta(minutes=1)).timestamp() * 1000000) + + json_data = { + "query": { + "sql": 'select * from "_rumlog" order by _timestamp desc limit 1 ;', + "start_time": one_min_ago, + "end_time": end_time, + "from": 0, + "size": 150, + "sql_mode": "full", + }, + } + + search_url = f"{base_url}api/{rum_org}/_search" + response_rum_data = session.post(search_url, params=params, json=json_data) + + # First check if the response is 200. + got = response_rum_data.status_code + expected = 200 + assert ( + expected == got + ), f"Failed to retrieve rum-logs, got = {got}, expected = {expected}, {response_rum_data.content}" + + response_payload = response_rum_data.json() + + assert len(response_payload["hits"]) > 0, "No results found in rum-logs" + logs_exist = any( + [ + x + for x in response_payload["hits"] + if x["message"] == unique_test_identifier + ] + ) + assert ( + logs_exist + ), f"Failed to retrieve the rum-log, {response_rum_data.content}" + assert response_payload["hits"][0].get("geo_info_country") is not None + break + except Exception as e: + if retries > 0: + retries -= 1 + time.sleep(3) + print("retrying - exception was ", e) + continue + else: + raise e diff --git a/tests/api-testing/tests/test_users.py b/tests/api-testing/tests/test_users.py new file mode 100644 index 0000000000..c2789c46bb --- /dev/null +++ b/tests/api-testing/tests/test_users.py @@ -0,0 +1,264 @@ +def test_e2e_users(create_session, base_url): + """Running an E2E test for get all the users list.""" + + session = create_session + url = base_url + org_id = "default" + + resp_get_allusers = session.get(f"{url}api/{org_id}/users") + + print(resp_get_allusers.content) + assert ( + resp_get_allusers.status_code == 200 + ), f"Get all functions list 200, but got {resp_get_allusers.status_code} {resp_get_allusers.content}" + + +def test_e2e_createusers(create_session, base_url): + """Running an E2E test for new user creation.""" + + session = create_session + url = base_url + org_id = "default" + payload = { + "organization": "e2e", + "email": "pytests@gmail.com", + "password": "Test@029w0", + "first_name": "Nehapd", + "last_name": "p", + "role": "admin", + } + + resp_create_users = session.post(f"{url}api/{org_id}/users", json=payload) + + print(resp_create_users.content) + assert ( + resp_create_users.status_code == 200 + ), f"Creating a user 200, but got {resp_create_users.status_code} {resp_create_users.content}" + resp_delete_users = session.delete(f"{url}api/{org_id}/users/pytests@gmail.com") + assert ( + resp_delete_users.status_code == 200 + ), f"Deleting this user, but got {resp_delete_users.status_code} {resp_delete_users.content}" + + +# def test_e2e_createusersasmember(create_session,base_url): +# """Running an E2E test for new user creation.""" + +# session = create_session +# url = base_url +# org_id = "default" +# payload = { +# "organization": "default", +# "email": "pytests@gmail.com", +# "password": "Test@029w0", +# "first_name": "Nehapd", +# "last_name": "p", +# "role": "member" +# } + +# resp_create_users = session.post(f"{url}api/{org_id}/users",json=payload) + +# print(resp_create_users.content) +# assert resp_create_users.status_code == 200, f"Creating a user 200, but got {resp_create_users.status_code} {resp_create_users.content}" +# resp_delete_users = session.delete(f"{url}api/{org_id}/users/pytests@gmail.com") +# assert resp_delete_users.status_code == 200, f"Deleting this user, but got {resp_delete_users.status_code} {resp_delete_users.content}" + + +def test_e2e_invalidrole(create_session, base_url): + """Running an E2E test for invalid role added.""" + + session = create_session + url = base_url + org_id = "default" + payload = { + "organization": "e2e", + "email": "pytests@gmail.com", + "password": "T", + "first_name": "Nehapd", + "last_name": "p", + "role": "m", + } + + resp_create_users = session.post(f"{url}api/{org_id}/users", json=payload) + + print(resp_create_users.content) + assert ( + resp_create_users.status_code == 400 + ), f"Invalid role added, but got {resp_create_users.status_code} {resp_create_users.content}" + + +# TODO = PLEASE change this testcase once bug fixed, add 400 and remove delete bug1679 +def test_e2e_invalidorganization(create_session, base_url): + """Running an E2E test for invalid org added while user creation.""" + + session = create_session + url = base_url + org_id = "default" + payload = { + "organization": "", + "email": "pytests@gmail.com", + "password": "T", + "first_name": "Nehapd", + "last_name": "p", + "role": "admin", + } + + resp_create_users = session.post(f"{url}api/{org_id}/users", json=payload) + + print(resp_create_users.content) + assert ( + resp_create_users.status_code == 200 + ), f"Invalid org added, but got {resp_create_users.status_code} {resp_create_users.content}" + resp_delete_users = session.delete(f"{url}api/{org_id}/users/pytests@gmail.com") + assert ( + resp_delete_users.status_code == 200 + ), f"Deleting this user, but got {resp_delete_users.status_code} {resp_delete_users.content}" + + +def test_e2e_addinvalidusertoOrg(create_session, base_url): + """Running an E2E test for invalid user added to org.""" + + session = create_session + url = base_url + org_id = "default" + payload = { + "organization": "e2e", + "email": "py@gmail.com", + "password": "T", + "first_name": "Nehapd", + "last_name": "p", + "role": "admin", + } + + resp_create_users = session.post( + f"{url}api/{org_id}/users/pynew@gmail.com", json=payload + ) + + print(resp_create_users.content) + assert ( + resp_create_users.status_code == 404 + ), f"Invalid role added 404, but got {resp_create_users.status_code} {resp_create_users.content}" + + +def test_e2e_updateuser(create_session, base_url): + """Running an E2E test for adding, updating & deleting user .""" + + session = create_session + url = base_url + org_id = "default" + payload = { + "organization": "e2e", + "email": "py@gmail.com", + "password": "T", + "first_name": "Nehapd", + "last_name": "p", + "role": "admin", + } + + resp_create_users = session.post(f"{url}api/{org_id}/users", json=payload) + + print(resp_create_users.content) + assert ( + resp_create_users.status_code == 200 + ), f"Creating a user 200, but got {resp_create_users.status_code} {resp_create_users.content}" + + payload = { + "organization": "e2e", + "email": "py@gmail.com", + "password": "T", + "first_name": "Editedname", + "last_name": "p", + "role": "admin", + } + resp_update_users = session.put( + f"{url}api/{org_id}/users/py@gmail.com", json=payload + ) + assert ( + resp_update_users.status_code == 200 + ), f"Update this user 200, but got {resp_update_users.status_code} {resp_update_users.content}" + resp_delete_users = session.delete(f"{url}api/{org_id}/users/py@gmail.com") + assert ( + resp_delete_users.status_code == 200 + ), f"Deleting this user, but got {resp_delete_users.status_code} {resp_delete_users.content}" + + +def test_e2e_updateusernotfound(create_session, base_url): + """Running an E2E test for user not found for updating values.""" + + session = create_session + url = base_url + org_id = "default" + payload = { + "organization": "e2e", + "email": "py@gmail.com", + "password": "T", + "first_name": "Nehapd", + "last_name": "p", + "role": "admin", + } + + resp_create_users = session.post(f"{url}api/{org_id}/users", json=payload) + + print(resp_create_users.content) + assert ( + resp_create_users.status_code == 200 + ), f"Creating a user 200, but got {resp_create_users.status_code} {resp_create_users.content}" + + payload = { + "organization": "default", + "email": "py@gmail.com", + "password": "T", + "first_name": "Editedname", + "last_name": "p", + "role": "admin", + } + resp_delete_users = session.delete(f"{url}api/{org_id}/users/py@gmail.com") + assert ( + resp_delete_users.status_code == 200 + ), f"Deleting this user, but got {resp_delete_users.status_code} {resp_delete_users.content}" + resp_update_users = session.put( + f"{url}api/{org_id}/users/py@gmail.com", json=payload + ) + assert ( + resp_update_users.status_code == 404 + ), f"Update this user 400, but got {resp_update_users.status_code} {resp_update_users.content}" + + +def test_e2e_updateuserexists(create_session, base_url): + """Running an E2E test for user already exists.""" + + session = create_session + url = base_url + org_id = "default" + payload = { + "organization": "default", + "email": "py@gmail.com", + "password": "T", + "first_name": "Nehapd", + "last_name": "p", + "role": "admin", + } + + resp_create_users = session.post(f"{url}api/{org_id}/users", json=payload) + + print(resp_create_users.content) + assert ( + resp_create_users.status_code == 200 + ), f"Creating a user 200, but got {resp_create_users.status_code} {resp_create_users.content}" + + payload = { + "organization": "default", + "email": "py@gmail.com", + "password": "T", + "first_name": "Nehapd", + "last_name": "p", + "role": "admin", + } + print(resp_create_users.content) + resp_create_users = session.post(f"{url}api/{org_id}/users", json=payload) + assert ( + resp_create_users.status_code == 400 + ), f"User already exists 400, but got {resp_create_users.status_code} {resp_create_users.content}" + resp_delete_users = session.delete(f"{url}api/{org_id}/users/py@gmail.com") + assert ( + resp_delete_users.status_code == 200 + ), f"Deleting this user 200, but got {resp_delete_users.status_code} {resp_delete_users.content}"