Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,27 @@ jobs:
command: |
make test-${{ env.python-version }}

test-vetiver:
name: "Vetiver integration test"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.12.4
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install '.[test,vetiver-testing]'
- name: Run tests
uses: posit-dev/with-connect@main
with:
version: "release"
license: ${{ secrets.CONNECT_LICENSE_FILE }}
command: |
pip freeze > requirements.txt
pytest -m 'vetiver'

test-dev-connect:
name: "Integration tests against dev Connect"
runs-on: ubuntu-latest
Expand All @@ -187,8 +208,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -r vetiver-testing/vetiver-requirements.txt
python -m pip install '.[test]'
python -m pip install '.[test,vetiver-testing]'
- name: Run Posit Connect
run: |
docker compose up --build -d
Expand Down
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ test = [
]
snowflake = ["snowflake-cli"]
mcp = ["fastmcp==2.12.4; python_version >= '3.10'"]
vetiver-testing = [
"pandas",
"numpy",
"pydantic",
"pytest",
"pins",
"vetiver",
]
docs = [
"mkdocs-material",
"mkdocs-click",
Expand Down
21 changes: 13 additions & 8 deletions tests/test_main_system_caches.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
from click.testing import CliRunner

from rsconnect.main import cli
from .utils import require_connect


CONNECT_SERVER = "http://localhost:3939"
CONNECT_KEYS_JSON = "vetiver-testing/rsconnect_api_keys.json"
CONNECT_CACHE_DIR = "/data/python-environments/_packages_cache"

Expand Down Expand Up @@ -64,11 +64,12 @@ def tearDownClass(cls):

# Admins can list caches
def test_system_caches_list_admin(self):
connect_server = require_connect()
api_key = get_key("admin")
runner = CliRunner()

args = ["system", "caches", "list"]
apply_common_args(args, server=CONNECT_SERVER, key=api_key)
apply_common_args(args, server=connect_server, key=api_key)

result = runner.invoke(cli, args)
self.assertEqual(result.exit_code, 0)
Expand All @@ -79,11 +80,12 @@ def test_system_caches_list_admin(self):

# Publishers cannot list caches
def test_system_caches_list_publisher(self):
connect_server = require_connect()
api_key = get_key("susan")
runner = CliRunner()

args = ["system", "caches", "list"]
apply_common_args(args, server=CONNECT_SERVER, key=api_key)
apply_common_args(args, server=connect_server, key=api_key)

result = runner.invoke(cli, args)
self.assertEqual(result.exit_code, 1)
Expand All @@ -106,11 +108,12 @@ def tearDownClass(cls):

# Publishers cannot delete caches
def test_system_caches_delete_publisher(self):
connect_server = require_connect()
api_key = get_key("susan")
runner = CliRunner()

args = ["system", "caches", "delete", "--language", "Python", "--version", "1.2.3", "--image-name", "Local"]
apply_common_args(args, server=CONNECT_SERVER, key=api_key)
apply_common_args(args, server=connect_server, key=api_key)

result = runner.invoke(cli, args)
self.assertEqual(result.exit_code, 1)
Expand All @@ -119,11 +122,12 @@ def test_system_caches_delete_publisher(self):

# Admins can delete caches that exist
def test_system_caches_delete_admin(self):
connect_server = require_connect()
api_key = get_key("admin")
runner = CliRunner()

args = ["system", "caches", "delete", "--language", "Python", "--version", "1.2.3", "--image-name", "Local"]
apply_common_args(args, server=CONNECT_SERVER, key=api_key)
apply_common_args(args, server=connect_server, key=api_key)

self.assertTrue(cache_dir_exists())
result = runner.invoke(cli, args)
Expand All @@ -134,26 +138,27 @@ def test_system_caches_delete_admin(self):

# --version and --language flags are required
def test_system_caches_delete_required_flags(self):
connect_server = require_connect()
api_key = get_key("admin")
runner = CliRunner()

# neither flag provided should fail
args = ["system", "caches", "delete"]
apply_common_args(args, server=CONNECT_SERVER, key=api_key)
apply_common_args(args, server=connect_server, key=api_key)
result = runner.invoke(cli, args)
self.assertEqual(result.exit_code, 2)
self.assertRegex(result.output, "Error: Missing option '--language' / '-l'")

# only --language flag provided should fail
args = ["system", "caches", "delete", "--language", "Python"]
apply_common_args(args, server=CONNECT_SERVER, key=api_key)
apply_common_args(args, server=connect_server, key=api_key)
result = runner.invoke(cli, args)
self.assertEqual(result.exit_code, 2)
self.assertRegex(result.output, "Error: Missing option '--version' / '-V'")

# only --version flag provided should fail
args = ["system", "caches", "delete", "--version", "1.2.3"]
apply_common_args(args, server=CONNECT_SERVER, key=api_key)
apply_common_args(args, server=connect_server, key=api_key)
result = runner.invoke(cli, args)
self.assertEqual(result.exit_code, 2)
self.assertRegex(result.output, "Error: Missing option '--language' / '-l'")
62 changes: 12 additions & 50 deletions tests/test_vetiver_pins.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,79 +2,41 @@

vetiver = pytest.importorskip("vetiver", reason="vetiver library not installed")

import json # noqa
import os # noqa
import pins # noqa
import pandas as pd # noqa
import numpy as np # noqa

from pins.boards import BoardRsConnect # noqa
from pins.rsconnect.api import RsConnectApi # noqa
from pins.rsconnect.fs import RsConnectFs # noqa
from rsconnect.api import RSConnectServer, RSConnectClient # noqa

RSC_SERVER_URL = "http://localhost:3939"
RSC_KEYS_FNAME = "vetiver-testing/rsconnect_api_keys.json"
from .utils import require_api_key, require_connect # noqa

pytestmark = pytest.mark.vetiver # noqa

os.environ["CONNECT_CONTENT_BUILD_DIR"] = "vetiver-test-build" # noqa

def get_key(name):
with open(RSC_KEYS_FNAME) as f:
api_key = json.load(f)[name]
return api_key


def rsc_from_key(name):
with open(RSC_KEYS_FNAME) as f:
api_key = json.load(f)[name]
return RsConnectApi(RSC_SERVER_URL, api_key)


def rsc_fs_from_key(name):

rsc = rsc_from_key(name)

return RsConnectFs(rsc)


def rsc_delete_user_content(rsc):
guid = rsc.get_user()["guid"]
content = rsc.get_content(owner_guid=guid)
for entry in content:
rsc.delete_content_item(entry["guid"])


@pytest.fixture(scope="function")
def rsc_short():
# tears down content after each test
fs_susan = rsc_fs_from_key("susan")

# delete any content that might already exist
rsc_delete_user_content(fs_susan.api)

yield BoardRsConnect("", fs_susan, allow_pickle_read=True) # fs_susan.ls to list content

rsc_delete_user_content(fs_susan.api)


def test_deploy(rsc_short):
def test_deploy():
server_url = require_connect()
np.random.seed(500)

# Load data, model
X_df, y = vetiver.mock.get_mock_data()
model = vetiver.mock.get_mock_model().fit(X_df, y)

v = vetiver.VetiverModel(model=model, prototype_data=X_df, model_name="susan/model")
board = pins.board_rsconnect(server_url=server_url, api_key=require_api_key(), allow_pickle_read=True)
username = board.fs.api.get_user()["username"]
modelname = f"{username}/model"

board = pins.board_rsconnect(server_url=RSC_SERVER_URL, api_key=get_key("susan"), allow_pickle_read=True)
v = vetiver.VetiverModel(model=model, prototype_data=X_df, model_name=modelname)

vetiver.vetiver_pin_write(board=board, model=v)
connect_server = RSConnectServer(url=RSC_SERVER_URL, api_key=get_key("susan"))
connect_server = RSConnectServer(url=server_url, api_key=require_api_key())

vetiver.deploy_rsconnect(
connect_server=connect_server,
board=board,
pin_name="susan/model",
pin_name=modelname,
title="testapivetiver",
extra_files=["requirements.txt"],
)
Expand All @@ -85,7 +47,7 @@ def test_deploy(rsc_short):
rsc_api = list(filter(lambda x: x["title"] == "testapivetiver", dicts))
content_url = rsc_api[0].get("content_url")

h = {"Authorization": "Key {}".format(get_key("susan"))}
h = {"Authorization": "Key {}".format(require_api_key())}

endpoint = vetiver.vetiver_endpoint(content_url + "/predict")
response = vetiver.predict(endpoint, X_df, headers=h)
Expand Down
6 changes: 0 additions & 6 deletions vetiver-testing/vetiver-requirements.txt

This file was deleted.

Loading