streamlit

Форк
0
/
cli_regression_tests.py 
216 строк · 7.8 Кб
1
#!/usr/bin/env python
2

3
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2024)
4
#
5
# Licensed under the Apache License, Version 2.0 (the "License");
6
# you may not use this file except in compliance with the License.
7
# You may obtain a copy of the License at
8
#
9
#     http://www.apache.org/licenses/LICENSE-2.0
10
#
11
# Unless required by applicable law or agreed to in writing, software
12
# distributed under the License is distributed on an "AS IS" BASIS,
13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
# See the License for the specific language governing permissions and
15
# limitations under the License.
16

17
import os
18
import signal
19
import subprocess
20
from typing import Optional
21

22
import pytest
23

24
CONFIG_FILE_PATH: str
25
CREDENTIALS_FILE_PATH: str
26
REPO_ROOT: str
27
STREAMLIT_RELEASE_VERSION: Optional[str]
28

29

30
class TestCLIRegressions:
31
    """Suite of CLI regression tests to be run against a release build of the Streamlit library.
32

33
    Before running, ensure that you have:
34
        - An isolated environment with Streamlit installed in production mode (not development) as
35
          well as pytest. This can include the current version, nightly, or local build/wheel, like
36
          one of the following:
37
                pip install streamlit-nightly=[nightly tag]
38
                pip install lib/dist/<WHEEL_FILE>
39
                pip install streamlit
40
        - The STREAMLIT_RELEASE_VERSION environment variable must be set, such as:
41
                export STREAMLIT_RELEASE_VERSION=1.5.1
42

43
    You can then run the tests from the root of the Streamlit repository using one of the following:
44
            pytest scripts/cli_regression_tests.py
45
            make cli-regression-tests
46

47
    This test suite makes use of Python's built-in assert statement. Note that assertions in the
48
    form of `assert <expression>` use Pytest's assertion introspection. In some cases, a more clear
49
    error message is specified manually by using `assert <expression>, <message>`. See
50
    https://docs.pytest.org/en/7.0.x/how-to/assert.html#assert-details for more details.
51
    """
52

53
    @pytest.fixture(scope="module", autouse=True)
54
    def setup(self):
55
        # ---- Initialization
56
        global CONFIG_FILE_PATH
57
        CONFIG_FILE_PATH = os.path.expanduser("~/.streamlit/config.toml")
58

59
        global CREDENTIALS_FILE_PATH
60
        CREDENTIALS_FILE_PATH = os.path.expanduser("~/.streamlit/credentials.toml")
61

62
        global REPO_ROOT
63
        REPO_ROOT = os.getcwd()
64

65
        global STREAMLIT_RELEASE_VERSION
66
        STREAMLIT_RELEASE_VERSION = os.environ.get("STREAMLIT_RELEASE_VERSION", None)
67

68
        # Ensure that there aren't any previously stored credentials
69
        if os.path.exists(CREDENTIALS_FILE_PATH):
70
            os.remove(CREDENTIALS_FILE_PATH)
71

72
        yield  # Run tests
73

74
        # ---- Tear Down
75
        # Remove testing credentials
76
        if os.path.exists(CREDENTIALS_FILE_PATH):
77
            os.remove(CREDENTIALS_FILE_PATH)
78

79
        if os.path.exists(CONFIG_FILE_PATH):
80
            os.remove(CONFIG_FILE_PATH)
81

82
        self.run_command("streamlit cache clear")
83

84
    def parameterize(self, params):
85
        return params.split(" ")
86

87
    def read_process_output(self, proc, num_lines_to_read):
88
        num_lines_read = 0
89
        output = ""
90

91
        while num_lines_read < num_lines_to_read:
92
            output += proc.stdout.readline().decode("UTF-8")
93
            num_lines_read += 1
94

95
        return output
96

97
    def run_command(self, command):
98
        return subprocess.check_output(self.parameterize(command)).decode("UTF-8")
99

100
    def run_single_proc(self, command, num_lines_to_read=4):
101
        proc = subprocess.Popen(
102
            command,
103
            shell=True,
104
            stdout=subprocess.PIPE,
105
            stderr=subprocess.STDOUT,
106
            preexec_fn=os.setpgrp,
107
        )
108

109
        output = self.read_process_output(proc, num_lines_to_read)
110

111
        try:
112
            os.kill(os.getpgid(proc.pid), signal.SIGTERM)
113
        except ProcessLookupError:
114
            # The process may have exited already. If so, we don't need to do anything
115
            pass
116

117
        return output
118

119
    def run_double_proc(
120
        self, command_one, command_two, wait_in_seconds=2, num_lines_to_read=4
121
    ):
122
        proc_one = subprocess.Popen(
123
            command_one,
124
            shell=True,
125
            stdout=subprocess.PIPE,
126
            stderr=subprocess.STDOUT,
127
            preexec_fn=os.setpgrp,
128
        )
129

130
        # Getting the output from process one ensures the process started first
131
        output_one = self.read_process_output(proc_one, num_lines_to_read)
132

133
        proc_two = subprocess.Popen(
134
            command_two,
135
            shell=True,
136
            stdout=subprocess.PIPE,
137
            stderr=subprocess.STDOUT,
138
            preexec_fn=os.setpgrp,
139
        )
140

141
        output_two = self.read_process_output(proc_two, num_lines_to_read)
142

143
        try:
144
            os.killpg(os.getpgid(proc_one.pid), signal.SIGKILL)
145
            os.killpg(os.getpgid(proc_two.pid), signal.SIGKILL)
146
        except ProcessLookupError:
147
            # The process may have exited already. If so, we don't need to do anything
148
            pass
149

150
        return output_one, output_two
151

152
    @pytest.mark.skipif(
153
        bool(os.environ.get("SKIP_VERSION_CHECK", False)) == True,
154
        reason="Skip version verification when `SKIP_VERSION_CHECK` env var is set",
155
    )
156
    def test_streamlit_version(self):
157
        assert (
158
            STREAMLIT_RELEASE_VERSION != None and STREAMLIT_RELEASE_VERSION != ""
159
        ), "You must set the $STREAMLIT_RELEASE_VERSION env variable"
160
        assert STREAMLIT_RELEASE_VERSION in self.run_command(
161
            "streamlit version"
162
        ), f"Package version does not match the desired version of {STREAMLIT_RELEASE_VERSION}"
163

164
    def test_streamlit_activate(self):
165
        process = subprocess.Popen(
166
            "streamlit activate", stdin=subprocess.PIPE, shell=True
167
        )
168
        process.stdin.write(b"regressiontest@streamlit.io\n")  # type: ignore
169
        process.stdin.flush()  # type: ignore
170
        process.communicate()
171

172
        with open(CREDENTIALS_FILE_PATH) as f:
173
            assert (
174
                "regressiontest@streamlit.io" in f.read()
175
            ), "Email address was not found in the credentials file"
176

177
    def test_port_reassigned(self):
178
        """When starting a new Streamlit session, it will run on port 8501 by default. If 8501 is
179
        not available, it will use the next available port.
180
        """
181

182
        out_one, out_two = self.run_double_proc(
183
            f"streamlit run --server.headless=true {REPO_ROOT}/examples/file_uploader.py",
184
            f"streamlit run --server.headless=true {REPO_ROOT}/examples/file_uploader.py",
185
        )
186

187
        assert ":8501" in out_one, f"Incorrect port. See output:\n{out_one}"
188
        assert ":8502" in out_two, f"Incorrect port. See output:\n{out_two}"
189

190
    def test_conflicting_port(self):
191
        out_one, out_two = self.run_double_proc(
192
            f"streamlit run --server.headless=true {REPO_ROOT}/examples/file_uploader.py",
193
            f"streamlit run --server.headless=true --server.port=8501 {REPO_ROOT}/examples/file_uploader.py",
194
        )
195

196
        assert ":8501" in out_one, f"Incorrect port. See output:\n{out_one}"
197
        assert (
198
            "Port 8501 is already in use" in out_two
199
        ), f"Incorrect conflict. See output:\n{out_one}"
200

201
    def test_cli_defined_port(self):
202
        out = self.run_single_proc(
203
            f"streamlit run --server.headless=true --server.port=9999 {REPO_ROOT}/examples/file_uploader.py",
204
        )
205

206
        assert ":9999" in out, f"Incorrect port. See output:\n{out}"
207

208
    def test_config_toml_defined_port(self):
209
        with open(CONFIG_FILE_PATH, "w") as file:
210
            file.write("[server]\n  port=8888")
211

212
        out = self.run_single_proc(
213
            f"streamlit run --server.headless=true {REPO_ROOT}/examples/file_uploader.py",
214
        )
215

216
        assert ":8888" in out, f"Incorrect port. See output:\n{out}"
217

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.