Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Skeleton for endpoint tests #708

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
adece42
tests
HansKallekleiv Aug 27, 2024
8874a4b
Merge branch 'main' of github.com:equinor/webviz into endpoint-tests
HansKallekleiv Aug 27, 2024
61e4524
bump pytest
HansKallekleiv Aug 27, 2024
cc28136
Merge branch 'main' of github.com:equinor/webviz into endpoint-tests
HansKallekleiv Sep 2, 2024
886b013
drogon test file wip
HansKallekleiv Sep 2, 2024
5f674eb
Add pytest timeout
HansKallekleiv Sep 2, 2024
f76af92
update workflow
HansKallekleiv Sep 2, 2024
cfe9ca2
wip
HansKallekleiv Sep 2, 2024
b35959b
wip
HansKallekleiv Sep 2, 2024
67a9697
wip
HansKallekleiv Sep 2, 2024
85cf93c
wip
HansKallekleiv Sep 2, 2024
073a8b2
wip
HansKallekleiv Sep 2, 2024
d4b3e31
wip
HansKallekleiv Sep 2, 2024
86c2ac5
wip
HansKallekleiv Sep 2, 2024
7d03be1
wip
HansKallekleiv Sep 2, 2024
0082243
wip
HansKallekleiv Sep 2, 2024
d3363a9
wip
HansKallekleiv Sep 2, 2024
1d97d9c
wip
HansKallekleiv Sep 2, 2024
57faf45
wip
HansKallekleiv Sep 2, 2024
08beb4f
wip
HansKallekleiv Sep 2, 2024
1a69a0b
wip
HansKallekleiv Sep 2, 2024
58f7d30
wip
HansKallekleiv Sep 2, 2024
312b08c
wip
HansKallekleiv Sep 2, 2024
a56cbd5
wip
HansKallekleiv Sep 2, 2024
db4c519
wip
HansKallekleiv Sep 2, 2024
c220b87
wip
HansKallekleiv Sep 2, 2024
2a325b2
wip
HansKallekleiv Sep 2, 2024
480690f
wip
HansKallekleiv Sep 2, 2024
549473f
wip
HansKallekleiv Sep 2, 2024
5e3d2c6
wip
HansKallekleiv Sep 2, 2024
4f90fb1
wip
HansKallekleiv Sep 2, 2024
4606f8c
wip
HansKallekleiv Sep 2, 2024
6ab56a8
wip
HansKallekleiv Sep 3, 2024
ebb65cb
Merge branch 'main' of github.com:equinor/webviz into endpoint-tests
HansKallekleiv Sep 3, 2024
4a6c0b5
wip
HansKallekleiv Sep 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions .github/workflows/backend_sumo_prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Test access DROGON-READ shared-key

on:
push:
branches:
- main
release:
types:
- published
workflow_dispatch:
# schedule:
# - cron: "48 4 * * *"

jobs:
build_pywheels:
name: PY ${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.11"]
os: [ubuntu-latest]
permissions:
contents: read
id-token: write

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

# - name: 🐍 Set up Python
# uses: actions/setup-python@v4
# with:
# python-version: "3.11"
# cache: pip

# - name: Install fmu-sumo
# run: >
# python -m pip install --upgrade pip &&
# python -m pip install .[test]

- name: 📦 Install poetry and dependencies
working-directory: ./backend_py/primary
run: |
pip install --upgrade pip
pip install poetry
poetry config virtualenvs.create false
poetry lock --check --no-update # Check lock file is consistent with pyproject.toml
poetry install --with dev

- name: 🤖 Run tests
working-directory: ./backend_py/primary
env:
WEBVIZ_CLIENT_SECRET: 0
WEBVIZ_SMDA_SUBSCRIPTION_KEY: 0
WEBVIZ_SMDA_RESOURCE_SCOPE: 0
WEBVIZ_VDS_HOST_ADDRESS: 0
WEBVIZ_ENTERPRISE_SUBSCRIPTION_KEY: 0
WEBVIZ_SSDL_RESOURCE_SCOPE: 0
WEBVIZ_SUMU_ENV: prod
SHARED_KEY_SUMO_PROD: ${{ secrets.SHARED_KEY_DROGON_READ_PROD }}
run: |
echo "Length of SHARED_KEY_SUMO_PROD variable read from Github Secrets:" ${#SHARED_KEY_SUMO_PROD}
mkdir ~/.sumo
echo $SHARED_KEY_SUMO_PROD > ~/.sumo/9e5443dd-3431-4690-9617-31eed61cb55a.sharedkey
ls -l ~/.sumo/9e5443dd-3431-4690-9617-31eed61cb55a.sharedkey
pytest -s --timeout=300 ./tests/integration

# - name: Run tests
# shell: bash
# env:
# sharedkey: ${{ secrets.SHARED_KEY_DROGON_READ_DEV }}
# run: |
# pip list | grep -i sumo

# echo "Length of sharedkey variable read from Github Secrets:" ${#sharedkey}
# mkdir ~/.sumo
# echo $sharedkey > ~/.sumo/88d2b022-3539-4dda-9e66-853801334a86.sharedkey
# ls -l ~/.sumo/88d2b022-3539-4dda-9e66-853801334a86.sharedkey

# pytest -s --timeout=300 tests/test_access/tst_access_drogon_read_login.py
3,597 changes: 1,870 additions & 1,727 deletions backend_py/primary/poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion backend_py/primary/primary/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from primary.middleware.add_process_time_to_server_timing_middleware import AddProcessTimeToServerTimingMiddleware
from primary.routers.correlations.router import router as correlations_router
from primary.routers.dev.router import router as dev_router
from primary.routers.explore import router as explore_router
from primary.routers.explore.router import router as explore_router
from primary.routers.general import router as general_router
from primary.routers.graph.router import router as graph_router
from primary.routers.grid3d.router import router as grid3d_router
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,43 +8,21 @@
from primary.services.sumo_access.sumo_inspector import SumoInspector
from primary.services.utils.authenticated_user import AuthenticatedUser

router = APIRouter()


class FieldInfo(BaseModel):
field_identifier: str


class CaseInfo(BaseModel):
uuid: str
name: str
status: str
user: str
from . import schemas


class EnsembleInfo(BaseModel):
name: str
realization_count: int


class EnsembleDetails(BaseModel):
name: str
field_identifier: str
case_name: str
case_uuid: str
realizations: Sequence[int]
router = APIRouter()


@router.get("/fields")
async def get_fields(
authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user),
) -> List[FieldInfo]:
) -> List[schemas.FieldInfo]:
"""
Get list of fields
"""
sumo_inspector = SumoInspector(authenticated_user.get_sumo_access_token())
field_ident_arr = await sumo_inspector.get_fields_async()
ret_arr = [FieldInfo(field_identifier=field_ident.identifier) for field_ident in field_ident_arr]
ret_arr = [schemas.FieldInfo(field_identifier=field_ident.identifier) for field_ident in field_ident_arr]

return ret_arr

Expand All @@ -53,14 +31,14 @@ async def get_fields(
async def get_cases(
authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user),
field_identifier: str = Query(description="Field identifier"),
) -> List[CaseInfo]:
) -> List[schemas.CaseInfo]:
"""Get list of cases for specified field"""
sumo_inspector = SumoInspector(authenticated_user.get_sumo_access_token())
case_info_arr = await sumo_inspector.get_cases_async(field_identifier=field_identifier)

ret_arr: List[CaseInfo] = []
ret_arr: List[schemas.CaseInfo] = []

ret_arr = [CaseInfo(uuid=ci.uuid, name=ci.name, status=ci.status, user=ci.user) for ci in case_info_arr]
ret_arr = [schemas.CaseInfo(uuid=ci.uuid, name=ci.name, status=ci.status, user=ci.user) for ci in case_info_arr]

return ret_arr

Expand All @@ -69,22 +47,20 @@ async def get_cases(
async def get_ensembles(
authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user),
case_uuid: str = Path(description="Sumo case uuid"),
) -> List[EnsembleInfo]:
) -> List[schemas.EnsembleInfo]:
"""Get list of ensembles for a case"""
case_inspector = CaseInspector.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid)
iteration_info_arr = await case_inspector.get_iterations_async()

print(iteration_info_arr)

return [EnsembleInfo(name=it.name, realization_count=it.realization_count) for it in iteration_info_arr]
return [schemas.EnsembleInfo(name=it.name, realization_count=it.realization_count) for it in iteration_info_arr]


@router.get("/cases/{case_uuid}/ensembles/{ensemble_name}")
async def get_ensemble_details(
authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user),
case_uuid: str = Path(description="Sumo case uuid"),
ensemble_name: str = Path(description="Ensemble name"),
) -> EnsembleDetails:
) -> schemas.EnsembleDetails:
"""Get more detailed information for an ensemble"""

case_inspector = CaseInspector.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid)
Expand All @@ -95,7 +71,7 @@ async def get_ensemble_details(
if len(field_identifiers) != 1:
raise NotImplementedError("Multiple field identifiers not supported")

return EnsembleDetails(
return schemas.EnsembleDetails(
name=ensemble_name,
case_name=case_name,
case_uuid=case_uuid,
Expand Down
27 changes: 27 additions & 0 deletions backend_py/primary/primary/routers/explore/schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from typing import List, Sequence

from pydantic import BaseModel


class FieldInfo(BaseModel):
field_identifier: str


class CaseInfo(BaseModel):
uuid: str
name: str
status: str
user: str


class EnsembleInfo(BaseModel):
name: str
realization_count: int


class EnsembleDetails(BaseModel):
name: str
field_identifier: str
case_name: str
case_uuid: str
realizations: Sequence[int]
58 changes: 47 additions & 11 deletions backend_py/primary/primary/routers/parameters/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

from primary.auth.auth_helper import AuthHelper
from primary.services.sumo_access.parameter_access import ParameterAccess
from primary.services.sumo_access.parameter_types import EnsembleParameter, EnsembleSensitivity
from primary.services.utils.authenticated_user import AuthenticatedUser

from . import schemas
Expand Down Expand Up @@ -53,16 +52,25 @@ async def get_parameter(
case_uuid: str = Query(description="Sumo case uuid"),
ensemble_name: str = Query(description="Ensemble name"),
parameter_name: str = Query(description="Parameter name"),
) -> Optional[EnsembleParameter]:
) -> Optional[schemas.EnsembleParameter]:
"""Get a parameter in a given Sumo ensemble"""

access = await ParameterAccess.from_case_uuid_async(
authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name
)
parameters = (await access.get_parameters_and_sensitivities()).parameters
for parameter in parameters:
parameters_and_sensitivities = await access.get_parameters_and_sensitivities()
for parameter in parameters_and_sensitivities.parameters:
if parameter.name == parameter_name:
return parameter
return schemas.EnsembleParameter(
name=parameter.name,
is_logarithmic=parameter.is_logarithmic,
is_numerical=parameter.is_numerical,
is_constant=parameter.is_constant,
group_name=parameter.group_name,
descriptive_name=parameter.descriptive_name,
realizations=parameter.realizations,
values=parameter.values,
)
return None


Expand All @@ -71,12 +79,27 @@ async def get_parameters(
authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user),
case_uuid: str = Query(description="Sumo case uuid"),
ensemble_name: str = Query(description="Ensemble name"),
) -> List[EnsembleParameter]:
) -> List[schemas.EnsembleParameter]:
access = await ParameterAccess.from_case_uuid_async(
authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name
)
parameters = (await access.get_parameters_and_sensitivities()).parameters
return [parameter for parameter in parameters]
parameters_and_sensitivities = await access.get_parameters_and_sensitivities()
parameters_ret_arr: List[schemas.EnsembleParameter] = []
for parameter in parameters_and_sensitivities.parameters:
parameters_ret_arr.append(
schemas.EnsembleParameter(
name=parameter.name,
is_logarithmic=parameter.is_logarithmic,
is_numerical=parameter.is_numerical,
is_constant=parameter.is_constant,
group_name=parameter.group_name,
descriptive_name=parameter.descriptive_name,
realizations=parameter.realizations,
values=parameter.values,
)
)

return parameters_ret_arr


@router.get("/is_sensitivity_run/")
Expand All @@ -99,12 +122,25 @@ async def get_sensitivities(
authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user),
case_uuid: str = Query(description="Sumo case uuid"),
ensemble_name: str = Query(description="Ensemble name"),
) -> List[EnsembleSensitivity]:
) -> List[schemas.EnsembleSensitivity]:
"""Get sensitivities in a given Sumo ensemble"""

access = await ParameterAccess.from_case_uuid_async(
authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name
)

sensitivities = (await access.get_parameters_and_sensitivities()).sensitivities
return sensitivities if sensitivities else []
parameters_and_sensitivities = (await access.get_parameters_and_sensitivities())
sensitivities_ret_arr: List[schemas.EnsembleSensitivity] = []
for sensitivity in parameters_and_sensitivities.sensitivities:
sensitivities_ret_arr.append(
schemas.EnsembleSensitivity(
name=sensitivity.name,
type=sensitivity.type,
cases=[
schemas.EnsembleSensitivityCase(name=case.name, realizations=case.realizations)
for case in sensitivity.cases
],
)
)

return sensitivities_ret_arr
45 changes: 44 additions & 1 deletion backend_py/primary/primary/routers/parameters/schemas.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Optional
from enum import Enum
from typing import Optional, List, Union

from pydantic import BaseModel

Expand All @@ -8,3 +9,45 @@ class EnsembleParameterDescription(BaseModel):
group_name: Optional[str] = None
descriptive_name: Optional[str] = None
is_numerical: bool


class EnsembleParameter(BaseModel):
"""Description/data for a single parameter in an ensemble"""

name: str
is_logarithmic: bool
is_numerical: bool
is_constant: bool # all values are equal
group_name: Optional[str] = None
descriptive_name: Optional[str] = None
realizations: List[int]
values: Union[List[float], List[int], List[str]]


class SensitivityType(str, Enum):
MONTECARLO = "montecarlo"
SCENARIO = "scenario"


class EnsembleSensitivityCase(BaseModel):
"""Description/data for a single sensitivity case in an ensemble"""

name: str
realizations: List[int]


class EnsembleSensitivity(BaseModel):
"""Description/data for a single sensitivity in an ensemble"""

name: str
type: SensitivityType
cases: List[EnsembleSensitivityCase]


class EnsembleParameters(BaseModel): # Find a better name
"""Description/data for all parameters in an ensemble
type: "sensitivity" | "historymatch" | "prediction ??"
"""

parameters: List[EnsembleParameter]
sensitivities: Optional[List[EnsembleSensitivity]] = None
2 changes: 2 additions & 0 deletions backend_py/primary/primary/services/sumo_access/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@


def create_sumo_client(access_token: str) -> SumoClient:
if access_token == "DUMMY_TOKEN_FOR_TESTING":
access_token = None
sumo_client = SumoClient(env=config.SUMO_ENV, token=access_token, interactive=False)
return sumo_client

Expand Down
Loading
Loading