|
1 | | -import datetime |
2 | 1 | from time import time |
3 | | -from typing import Optional, Sequence, Tuple |
4 | | - |
5 | | -import click |
6 | | - |
7 | | -from launchable.utils.no_build import NO_BUILD_BUILD_NAME |
8 | | -from launchable.utils.tracking import TrackingClient |
9 | | - |
10 | | -from ..app import Application |
11 | | -from ..utils.launchable_client import LaunchableClient |
12 | | -from ..utils.session import read_build, read_session, validate_session_format |
13 | | - |
14 | | - |
15 | | -def require_session( |
16 | | - session: Optional[str], |
17 | | -) -> Optional[str]: |
18 | | - """Ascertain the contextual test session to operate a CLI command for. If one doesn't exit, fail. |
19 | | -
|
20 | | - 1. If the user explicitly provides the session id via the `--session` option |
21 | | - 2. If the user gives no options, the current session ID is read from the session file tied to $PWD. |
22 | | - See https://github.com/cloudbees-oss/smart-tests-cli/pull/342 |
23 | | - """ |
24 | | - if session: |
25 | | - validate_session_format(session) |
26 | | - return session |
27 | | - |
28 | | - session = read_session(require_build()) |
29 | | - if session: |
30 | | - return session |
31 | | - |
32 | | - raise click.UsageError( |
33 | | - click.style( |
34 | | - "No saved test session found.\n" |
35 | | - "If you already created a test session on a different machine, use the --session option. " |
36 | | - "See https://docs.launchableinc.com/sending-data-to-launchable/managing-complex-test-session-layouts", |
37 | | - fg="yellow")) |
38 | | - |
39 | | - |
40 | | -def require_build() -> str: |
41 | | - """ |
42 | | - Like read_build() but fail if a build doesn't exist |
43 | | - """ |
44 | | - b = read_build() |
45 | | - if not b: |
46 | | - raise click.UsageError( |
47 | | - click.style( |
48 | | - "No saved build name found.\n" |
49 | | - "To fix this, run `launchable record build`.\n" |
50 | | - "If you already ran this command on a different machine, use the --session option. " |
51 | | - "See https://www.launchableinc.com/docs/sending-data-to-launchable/using-the-launchable-cli/" |
52 | | - "recording-test-results-with-the-launchable-cli/managing-complex-test-session-layouts/", |
53 | | - fg="yellow")) |
54 | | - return b |
55 | | - |
56 | | - |
57 | | -def find_or_create_session( |
58 | | - context: click.core.Context, |
59 | | - session: Optional[str], |
60 | | - build_name: Optional[str], |
61 | | - tracking_client: TrackingClient, |
62 | | - flavor: Sequence[Tuple[str, str]] = (), |
63 | | - is_observation: bool = False, |
64 | | - links: Sequence[Tuple[str, str]] = (), |
65 | | - is_no_build: bool = False, |
66 | | - lineage: Optional[str] = None, |
67 | | - test_suite: Optional[str] = None, |
68 | | - timestamp: Optional[datetime.datetime] = None, |
69 | | -) -> Optional[str]: |
70 | | - """Determine the test session ID to be used. |
71 | | -
|
72 | | - 1. If the user explicitly provides the session id via the `--session` option |
73 | | - 2. If the user gives no options, the current session ID is read from the session file tied to $PWD, |
74 | | - or one is created from the current build name. See https://github.com/cloudbees-oss/smart-tests-cli/pull/342 |
75 | | - 3. The `--build` option is legacy compatible behaviour, in which case a session gets created and tied |
76 | | - to the build. This usage still requires a locally recorded build name that must match the specified name. |
77 | | - Kohsuke is not sure what the historical motivation for this behaviour is. |
78 | | -
|
79 | | - Args: |
80 | | - session: The --session option value |
81 | | - build_name: The --build option value |
82 | | - flavor: The --flavor option values |
83 | | - is_observation: The --observation value |
84 | | - links: The --link option values |
85 | | - is_no_build: The --no-build option value |
86 | | - lineage: lineage option value |
87 | | - test_suite: --test-suite option value |
88 | | - """ |
89 | | - from .record.session import session as session_command |
90 | | - |
91 | | - if session: |
92 | | - validate_session_format(session) |
93 | | - _check_observation_mode_status(session, is_observation, tracking_client=tracking_client, app=context.obj) |
94 | | - return session |
95 | | - |
96 | | - if is_no_build: |
97 | | - context.invoke( |
98 | | - session_command, |
99 | | - build_name=NO_BUILD_BUILD_NAME, |
100 | | - save_session_file=True, |
101 | | - print_session=False, |
102 | | - flavor=flavor, |
103 | | - is_observation=is_observation, |
104 | | - links=links, |
105 | | - is_no_build=is_no_build, |
106 | | - lineage=lineage, |
107 | | - test_suite=test_suite, |
108 | | - ) |
109 | | - saved_build_name = read_build() |
110 | | - return read_session(str(saved_build_name)) |
111 | | - |
112 | | - saved_build_name = require_build() |
113 | | - |
114 | | - if build_name and saved_build_name != build_name: |
115 | | - raise click.UsageError( |
116 | | - click.style( |
117 | | - "The build name you provided ({}) is different from the last build name recorded on this machine ({}).\n" |
118 | | - "Make sure to run `launchable record build --name {}` before you run this command.\n" |
119 | | - "If you already recorded this build on a different machine, use the --session option instead of --build. " |
120 | | - "See https://www.launchableinc.com/docs/sending-data-to-launchable/using-the-launchable-cli/" |
121 | | - "recording-test-results-with-the-launchable-cli/managing-complex-test-session-layouts/".format( |
122 | | - build_name, saved_build_name, build_name), fg="yellow", )) |
123 | | - |
124 | | - session_id = read_session(saved_build_name) |
125 | | - if session_id: |
126 | | - _check_observation_mode_status(session_id, is_observation, tracking_client=tracking_client, app=context.obj) |
127 | | - return session_id |
128 | | - |
129 | | - context.invoke( |
130 | | - session_command, |
131 | | - build_name=saved_build_name, |
132 | | - save_session_file=True, |
133 | | - print_session=False, |
134 | | - flavor=flavor, |
135 | | - is_observation=is_observation, |
136 | | - links=links, |
137 | | - is_no_build=is_no_build, |
138 | | - lineage=lineage, |
139 | | - test_suite=test_suite, |
140 | | - timestamp=timestamp, |
141 | | - ) |
142 | | - return read_session(saved_build_name) |
143 | 2 |
|
144 | 3 |
|
145 | 4 | def time_ns(): |
146 | 5 | # time.time_ns() method is new in Python version 3.7 |
147 | 6 | # As a workaround, we convert time.time() to nanoseconds. |
148 | 7 | return int(time() * 1e9) |
149 | | - |
150 | | - |
151 | | -def _check_observation_mode_status(session: str, is_observation: bool, |
152 | | - tracking_client: TrackingClient, app: Optional[Application] = None): |
153 | | - if not is_observation: |
154 | | - return |
155 | | - |
156 | | - client = LaunchableClient(tracking_client=tracking_client, app=app) |
157 | | - res = client.request("get", session) |
158 | | - |
159 | | - # only check when the status code is 200 not to stop the command |
160 | | - if res.status_code == 200: |
161 | | - is_observation_in_recorded_session = res.json().get("isObservation", False) |
162 | | - if is_observation and not is_observation_in_recorded_session: |
163 | | - click.echo( |
164 | | - click.style( |
165 | | - "WARNING: --observation flag was ignored. Observation mode can only be enabled for a test session " |
166 | | - "during its initial creation. " |
167 | | - "Add `--observation` option to the `launchable record session` command instead.", |
168 | | - fg='yellow'), |
169 | | - err=True) |
0 commit comments