Skip to content
Closed
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
162 changes: 0 additions & 162 deletions launchable/commands/helper.py
Original file line number Diff line number Diff line change
@@ -1,169 +1,7 @@
import datetime
from time import time
from typing import Optional, Sequence, Tuple

import click

from launchable.utils.no_build import NO_BUILD_BUILD_NAME
from launchable.utils.tracking import TrackingClient

from ..app import Application
from ..utils.launchable_client import LaunchableClient
from ..utils.session import read_build, read_session, validate_session_format


def require_session(
session: Optional[str],
) -> Optional[str]:
"""Ascertain the contextual test session to operate a CLI command for. If one doesn't exit, fail.

1. If the user explicitly provides the session id via the `--session` option
2. If the user gives no options, the current session ID is read from the session file tied to $PWD.
See https://github.com/cloudbees-oss/smart-tests-cli/pull/342
"""
if session:
validate_session_format(session)
return session

session = read_session(require_build())
if session:
return session

raise click.UsageError(
click.style(
"No saved test session found.\n"
"If you already created a test session on a different machine, use the --session option. "
"See https://docs.launchableinc.com/sending-data-to-launchable/managing-complex-test-session-layouts",
fg="yellow"))


def require_build() -> str:
"""
Like read_build() but fail if a build doesn't exist
"""
b = read_build()
if not b:
raise click.UsageError(
click.style(
"No saved build name found.\n"
"To fix this, run `launchable record build`.\n"
"If you already ran this command on a different machine, use the --session option. "
"See https://www.launchableinc.com/docs/sending-data-to-launchable/using-the-launchable-cli/"
"recording-test-results-with-the-launchable-cli/managing-complex-test-session-layouts/",
fg="yellow"))
return b


def find_or_create_session(
context: click.core.Context,
session: Optional[str],
build_name: Optional[str],
tracking_client: TrackingClient,
flavor: Sequence[Tuple[str, str]] = (),
is_observation: bool = False,
links: Sequence[Tuple[str, str]] = (),
is_no_build: bool = False,
lineage: Optional[str] = None,
test_suite: Optional[str] = None,
timestamp: Optional[datetime.datetime] = None,
) -> Optional[str]:
"""Determine the test session ID to be used.

1. If the user explicitly provides the session id via the `--session` option
2. If the user gives no options, the current session ID is read from the session file tied to $PWD,
or one is created from the current build name. See https://github.com/cloudbees-oss/smart-tests-cli/pull/342
3. The `--build` option is legacy compatible behaviour, in which case a session gets created and tied
to the build. This usage still requires a locally recorded build name that must match the specified name.
Kohsuke is not sure what the historical motivation for this behaviour is.

Args:
session: The --session option value
build_name: The --build option value
flavor: The --flavor option values
is_observation: The --observation value
links: The --link option values
is_no_build: The --no-build option value
lineage: lineage option value
test_suite: --test-suite option value
"""
from .record.session import session as session_command

if session:
validate_session_format(session)
_check_observation_mode_status(session, is_observation, tracking_client=tracking_client, app=context.obj)
return session

if is_no_build:
context.invoke(
session_command,
build_name=NO_BUILD_BUILD_NAME,
save_session_file=True,
print_session=False,
flavor=flavor,
is_observation=is_observation,
links=links,
is_no_build=is_no_build,
lineage=lineage,
test_suite=test_suite,
)
saved_build_name = read_build()
return read_session(str(saved_build_name))

saved_build_name = require_build()

if build_name and saved_build_name != build_name:
raise click.UsageError(
click.style(
"The build name you provided ({}) is different from the last build name recorded on this machine ({}).\n"
"Make sure to run `launchable record build --name {}` before you run this command.\n"
"If you already recorded this build on a different machine, use the --session option instead of --build. "
"See https://www.launchableinc.com/docs/sending-data-to-launchable/using-the-launchable-cli/"
"recording-test-results-with-the-launchable-cli/managing-complex-test-session-layouts/".format(
build_name, saved_build_name, build_name), fg="yellow", ))

session_id = read_session(saved_build_name)
if session_id:
_check_observation_mode_status(session_id, is_observation, tracking_client=tracking_client, app=context.obj)
return session_id

context.invoke(
session_command,
build_name=saved_build_name,
save_session_file=True,
print_session=False,
flavor=flavor,
is_observation=is_observation,
links=links,
is_no_build=is_no_build,
lineage=lineage,
test_suite=test_suite,
timestamp=timestamp,
)
return read_session(saved_build_name)


def time_ns():
# time.time_ns() method is new in Python version 3.7
# As a workaround, we convert time.time() to nanoseconds.
return int(time() * 1e9)


def _check_observation_mode_status(session: str, is_observation: bool,
tracking_client: TrackingClient, app: Optional[Application] = None):
if not is_observation:
return

client = LaunchableClient(tracking_client=tracking_client, app=app)
res = client.request("get", session)

# only check when the status code is 200 not to stop the command
if res.status_code == 200:
is_observation_in_recorded_session = res.json().get("isObservation", False)
if is_observation and not is_observation_in_recorded_session:
click.echo(
click.style(
"WARNING: --observation flag was ignored. Observation mode can only be enabled for a test session "
"during its initial creation. "
"Add `--observation` option to the `launchable record session` command instead.",
fg='yellow'),
err=True)
15 changes: 1 addition & 14 deletions launchable/commands/inspect/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

from ...utils.authentication import ensure_org_workspace
from ...utils.launchable_client import LaunchableClient
from ...utils.session import parse_session
from ..helper import require_session


class TestResult(object):
Expand Down Expand Up @@ -133,6 +131,7 @@ def display(self):
'--test-session-id',
'test_session_id',
help='test session id',
required=True,
)
@click.option(
'--json',
Expand All @@ -142,18 +141,6 @@ def display(self):
)
@click.pass_context
def tests(context: click.core.Context, test_session_id: int, is_json_format: bool):
if (test_session_id is None):
try:
session = require_session(None)
_, test_session_id = parse_session(session)
except Exception:
click.echo(
click.style(
"test session id requires.\n"
"Use the --test-session-id option or execute after `launchable record tests` command.",
fg="yellow"))
return

client = LaunchableClient(app=context.obj)
try:
res = client.request(
Expand Down
9 changes: 4 additions & 5 deletions launchable/commands/record/attachment.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from typing import Optional

import click

from ...utils.launchable_client import LaunchableClient
from ..helper import require_session
from ...utils.session import validate_session_format


@click.command()
Expand All @@ -12,17 +10,18 @@
'session',
help='In the format builds/<build-name>/test_sessions/<test-session-id>',
type=str,
required=True,
)
@click.argument('attachments', nargs=-1) # type=click.Path(exists=True)
@click.pass_context
def attachment(
context: click.core.Context,
attachments,
session: Optional[str] = None
session: str
):
client = LaunchableClient(app=context.obj)
try:
session = require_session(session)
validate_session_format(session)

for a in attachments:
click.echo("Sending {}".format(a))
Expand Down
6 changes: 0 additions & 6 deletions launchable/commands/record/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from ...utils.commands import Command
from ...utils.fail_fast_mode import set_fail_fast_mode, warn_and_exit_if_fail_fast_mode
from ...utils.launchable_client import LaunchableClient
from ...utils.session import clean_session_files, write_build
from .commit import commit

JENKINS_GIT_BRANCH_KEY = "GIT_BRANCH"
Expand Down Expand Up @@ -126,8 +125,6 @@ def build(
if not no_commit_collection and len(commits) != 0:
sys.exit("--no-commit-collection must be specified when --commit is used")

clean_session_files(days_ago=14)

# Information we want to collect for each Git repository
# The key data structure throughout the implementation of this command
class Workspace:
Expand Down Expand Up @@ -341,9 +338,6 @@ def compute_links():
res = client.request("post", "builds", payload=payload)
res.raise_for_status()

# at this point we've successfully send the data, so it's OK to record this build
write_build(build_name)

return res.json().get("id", None)
except Exception as e:
tracking_client.send_error_event(
Expand Down
25 changes: 1 addition & 24 deletions launchable/commands/record/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@

from ...utils.click import KEY_VALUE
from ...utils.commands import Command
from ...utils.fail_fast_mode import FailFastModeValidateParams, fail_fast_mode_validate, set_fail_fast_mode
from ...utils.fail_fast_mode import set_fail_fast_mode
from ...utils.launchable_client import LaunchableClient
from ...utils.no_build import NO_BUILD_BUILD_NAME
from ...utils.session import _session_file_path, read_build, write_session

LAUNCHABLE_SESSION_DIR_KEY = 'LAUNCHABLE_SESSION_DIR'

Expand All @@ -41,13 +40,6 @@ def _validate_session_name(ctx, param, value):
type=str,
metavar='BUILD_NAME'
)
@click.option(
'--save-file/--no-save-file',
'save_session_file',
help='save session to file',
default=True,
metavar='SESSION_FILE'
)
@click.option(
"--flavor",
"flavor",
Expand Down Expand Up @@ -114,7 +106,6 @@ def _validate_session_name(ctx, param, value):
def session(
ctx: click.core.Context,
build_name: str,
save_session_file: bool,
print_session: bool = True,
flavor: Sequence[Tuple[str, str]] = [],
is_observation: bool = False,
Expand All @@ -138,22 +129,10 @@ def session(
client = LaunchableClient(app=ctx.obj, tracking_client=tracking_client)
set_fail_fast_mode(client.is_fail_fast_mode())

fail_fast_mode_validate(FailFastModeValidateParams(
command=Command.RECORD_SESSION,
build=build_name,
is_no_build=is_no_build,
test_suite=test_suite,
))

if not is_no_build and not build_name:
raise click.UsageError("Error: Missing option '--build'")

if is_no_build:
build = read_build()
if build and build != "":
raise click.UsageError(
"The cli already created '{}'. If you want to use the '--no-build' option, please remove this file first.".format(_session_file_path())) # noqa: E501

build_name = NO_BUILD_BUILD_NAME

if session_name:
Expand Down Expand Up @@ -226,8 +205,6 @@ def session(
build_name = res.json().get("buildNumber", "")
sub_path = "builds/{}/test_sessions".format(build_name)

if save_session_file:
write_session(build_name, "{}/{}".format(sub_path, session_id))
if print_session:
# what we print here gets captured and passed to `--session` in
# later commands
Expand Down
Loading
Loading