11from __future__ import annotations
22
3+ import os
34from typing import Iterator
45
56import pytest
@@ -31,7 +32,7 @@ def _cleanup(client: Runloop) -> Iterator[None]: # pyright: ignore[reportUnused
3132_blueprint_name = unique_name ("bp" )
3233
3334
34- @pytest .mark .timeout (30 )
35+ @pytest .mark .timeout (120 ) # 2 minutes
3536def test_create_blueprint_and_await_build (client : Runloop ) -> None :
3637 global _blueprint_id
3738 created = client .blueprints .create_and_await_build_complete (
@@ -42,24 +43,65 @@ def test_create_blueprint_and_await_build(client: Runloop) -> None:
4243 _blueprint_id = created .id
4344
4445
45- @pytest .mark .timeout (30 )
46+ @pytest .mark .timeout (120 )
4647def test_start_devbox_from_base_blueprint_by_id (client : Runloop ) -> None :
4748 assert _blueprint_id
48- devbox = client .devboxes .create_and_await_running (
49- blueprint_id = _blueprint_id ,
50- polling_config = PollingConfig (max_attempts = 120 , interval_seconds = 5.0 , timeout_seconds = 20 * 60 ),
51- )
52- assert devbox .blueprint_id == _blueprint_id
53- assert devbox .status == "running"
54- client .devboxes .shutdown (devbox .id )
49+ devbox = None
50+ try :
51+ devbox = client .devboxes .create_and_await_running (
52+ blueprint_id = _blueprint_id ,
53+ polling_config = PollingConfig (max_attempts = 120 , interval_seconds = 5.0 , timeout_seconds = 20 * 60 ),
54+ )
55+ assert devbox .blueprint_id == _blueprint_id
56+ assert devbox .status == "running"
57+ finally :
58+ if devbox :
59+ client .devboxes .shutdown (devbox .id )
5560
5661
57- @pytest .mark .timeout (30 )
62+ @pytest .mark .timeout (120 )
5863def test_start_devbox_from_base_blueprint_by_name (client : Runloop ) -> None :
59- devbox = client .devboxes .create_and_await_running (
60- blueprint_name = _blueprint_name ,
61- polling_config = PollingConfig (max_attempts = 120 , interval_seconds = 5.0 , timeout_seconds = 20 * 60 ),
62- )
63- assert devbox .blueprint_id
64- assert devbox .status == "running"
65- client .devboxes .shutdown (devbox .id )
64+ devbox = None
65+ try :
66+ devbox = client .devboxes .create_and_await_running (
67+ blueprint_name = _blueprint_name ,
68+ polling_config = PollingConfig (max_attempts = 120 , interval_seconds = 5.0 , timeout_seconds = 20 * 60 ),
69+ )
70+ assert devbox .blueprint_id
71+ assert devbox .status == "running"
72+ finally :
73+ if devbox :
74+ client .devboxes .shutdown (devbox .id )
75+
76+
77+ @pytest .mark .timeout (120 )
78+ @pytest .mark .skipif (
79+ os .getenv ("RUN_SMOKETESTS" ) != "1" ,
80+ reason = "Skip blueprint secrets test in local testing (requires RUN_SMOKETESTS=1)" ,
81+ )
82+ def test_create_blueprint_with_secret_and_await_build (client : Runloop ) -> None :
83+ bpt = None
84+ try :
85+ bpt = client .blueprints .create (
86+ name = unique_name ("bp-secrets" ),
87+ dockerfile = (
88+ "FROM runloop:runloop/starter-arm64\n "
89+ "ARG GITHUB_TOKEN\n "
90+ 'RUN git config --global credential.helper \' !f() { echo "username=x-access-token"; echo "password=$GITHUB_TOKEN"; }; f\' '
91+ "&& git clone https://github.com/runloopai/runloop-fe.git /workspace/runloop-fe "
92+ "&& git config --global --unset credential.helper\n "
93+ "WORKDIR /workspace/runloop-fe"
94+ ),
95+ secrets = {"GITHUB_TOKEN" : "GITHUB_TOKEN_FOR_SMOKETESTS" },
96+ )
97+
98+ completed = client .blueprints .await_build_complete (
99+ bpt .id ,
100+ polling_config = PollingConfig (max_attempts = 180 , interval_seconds = 5.0 , timeout_seconds = 30 * 60 ),
101+ )
102+ assert completed .status == "build_complete"
103+ assert completed .parameters .secrets is not None
104+ assert completed .parameters .secrets .get ("GITHUB_TOKEN" ) == "GITHUB_TOKEN_FOR_SMOKETESTS"
105+ finally :
106+ if bpt :
107+ client .blueprints .delete (bpt .id )
0 commit comments