Skip to content

Commit

Permalink
Fixed nightly integration tests run as service principals (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
nfx authored Feb 24, 2024
1 parent aa57141 commit 01d9467
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 11 deletions.
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -459,12 +459,14 @@ from databricks.labs.blueprint.installation import Installation
ws = WorkspaceClient()

# current user installation
installation = Installation.current(ws, "blueprint", assume_user=True)
installation = Installation.assume_user_home(ws, "blueprint")
assert "/Users/foo/.blueprint" == installation.install_folder()
assert not installation.is_global()

# workspace global installation
installation = Installation.current(ws, "blueprint")
assert "/Applications/blueprint" == installation.install_folder()
assert installation.is_global()
```

[[back to top](#databricks-labs-blueprint)]
Expand All @@ -478,6 +480,17 @@ Let's say, users `foo@example.com` and `bar@example.com` installed `blueprint` p
code will print `/Workspace/bar@example.com/.blueprint` and `/Workspace/foo@example.com/.blueprint`:

```python
from databricks.sdk import WorkspaceClient
from databricks.labs.blueprint.installation import Installation

ws = WorkspaceClient()

global_install = Installation.assume_global(ws, 'blueprint')
global_install.upload("some.bin", b"...")

user_install = Installation.assume_user_home(ws, 'blueprint')
user_install.upload("some.bin", b"...")

for blueprint in Installation.existing(ws, "blueprint"):
print(blueprint.install_folder())
```
Expand Down
31 changes: 27 additions & 4 deletions src/databricks/labs/blueprint/installation.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def current(cls, ws: WorkspaceClient, product: str, *, assume_user: bool = False
will assume that the installation is in the user's home directory and return it if found. If False, the method
will only return an installation that is in the `/Applications` directory."""
user_folder = cls._user_home_installation(ws, product)
applications_folder = f"/Applications/{product}"
applications_folder = cls._global_installation(product)
folders = [user_folder, applications_folder]
for candidate in folders:
try:
Expand All @@ -84,6 +84,18 @@ def current(cls, ws: WorkspaceClient, product: str, *, assume_user: bool = False
return cls(ws, product, install_folder=user_folder)
raise NotInstalled(f"Application not installed: {product}")

@classmethod
def assume_user_home(cls, ws: WorkspaceClient, product: str):
"""Constructs installation with explicit location in the user home folder"""
user_folder = cls._user_home_installation(ws, product)
return cls(ws, product, install_folder=user_folder)

@classmethod
def assume_global(cls, ws: WorkspaceClient, product: str):
"""Constructs installation with explicit global location in the /Applications folder"""
applications_folder = cls._global_installation(product)
return cls(ws, product, install_folder=applications_folder)

@classmethod
def existing(cls, ws: WorkspaceClient, product: str) -> Collection["Installation"]:
"""Returns a collection of all existing installations for the given product in the current workspace.
Expand All @@ -98,10 +110,13 @@ def check_folder(install_folder: str) -> Installation | None:
except NotFound:
return None

tasks = [functools.partial(check_folder, f"/Applications/{product}")]
tasks = [functools.partial(check_folder, cls._global_installation(product))]
for user in ws.users.list(attributes="userName"):
user_folder = f"/Users/{user.user_name}/.{product}"
tasks.append(functools.partial(check_folder, user_folder))
service_principal_folder = f"/Users/{user.user_name}/.{product}"
tasks.append(functools.partial(check_folder, service_principal_folder))
for service_principal in ws.service_principals.list(attributes="applicationId"):
service_principal_folder = f"/Users/{service_principal.application_id}/.{product}"
tasks.append(functools.partial(check_folder, service_principal_folder))
return Threads.strict(f"finding {product} installations", tasks)

@classmethod
Expand Down Expand Up @@ -157,6 +172,10 @@ def install_folder(self) -> str:
self._install_folder = self._user_home_installation(self._ws, self.product())
return self._install_folder

def is_global(self) -> bool:
"""Returns true if current installation is in /Applications folder"""
return self.install_folder() == self._global_installation(self._product)

def username(self) -> str:
return os.path.basename(os.path.dirname(self.install_folder()))

Expand Down Expand Up @@ -310,6 +329,10 @@ def _overwrite_content(self, filename: str, as_dict: Json, type_ref: type):
raw = converters[extension](as_dict, type_ref)
self.upload(filename, raw)

@staticmethod
def _global_installation(product):
return f"/Applications/{product}"

@classmethod
def _unmarshal_type(cls, as_dict, filename, type_ref):
expected_version = None
Expand Down
10 changes: 4 additions & 6 deletions tests/integration/test_installation.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from dataclasses import dataclass
from datetime import timedelta

import pytest
from databricks.sdk.errors import PermissionDenied
from databricks.sdk.retries import retried
from databricks.sdk.service.provisioning import Workspace

from databricks.labs.blueprint.installation import Installation
Expand All @@ -24,23 +22,23 @@ def test_install_folder_custom(ws):
@pytest.mark.xfail(raises=PermissionDenied)
def test_detect_global(ws, make_random):
product = make_random(4)
Installation(ws, product, install_folder=f"/Applications/{product}").upload("some", b"...")
Installation.assume_global(ws, product).upload("some", b"...")

current = Installation.current(ws, product)

assert current.install_folder() == f"/Applications/{product}"
assert current.is_global()


# integration tests are running from lower-privileged environment
@pytest.mark.xfail(raises=PermissionDenied)
@retried(on=[AssertionError], timeout=timedelta(seconds=15))
def test_existing_installations_are_detected(ws, make_random):
product = make_random(4)

global_install = Installation(ws, product, install_folder=f"/Applications/{product}")
global_install = Installation.assume_global(ws, product)
global_install.upload("some", b"...")

user_install = Installation(ws, product)
user_install = Installation.assume_user_home(ws, product)
user_install.upload("some2", b"...")

existing = Installation.existing(ws, product)
Expand Down

0 comments on commit 01d9467

Please sign in to comment.