|
12 | 12 | # otherwise use the software for commercial activities involving the Arduino
|
13 | 13 | # software without disclosing the source code of your own applications. To purchase
|
14 | 14 | # a commercial license, send an email to license@arduino.cc.
|
15 |
| -import json |
16 |
| -import os |
17 |
| -import platform |
18 |
| - |
19 |
| -import pytest |
20 |
| - |
21 |
| -from .common import running_on_ci |
22 |
| - |
23 |
| - |
24 |
| -def test_compile_without_fqbn(run_command): |
25 |
| - # Init the environment explicitly |
26 |
| - result = run_command("core update-index") |
27 |
| - assert result.ok |
28 |
| - |
29 |
| - # Download latest AVR |
30 |
| - result = run_command("core install arduino:avr") |
31 |
| - assert result.ok |
32 |
| - |
33 |
| - # Build sketch without FQBN |
34 |
| - result = run_command("compile") |
35 |
| - assert result.failed |
36 |
| - |
37 |
| - |
38 |
| -def test_compile_with_simple_sketch(run_command, data_dir, working_dir): |
39 |
| - # Init the environment explicitly |
40 |
| - result = run_command("core update-index") |
41 |
| - assert result.ok |
42 |
| - |
43 |
| - # Download latest AVR |
44 |
| - result = run_command("core install arduino:avr") |
45 |
| - assert result.ok |
46 |
| - |
47 |
| - sketch_name = "CompileIntegrationTest" |
48 |
| - sketch_path = os.path.join(data_dir, sketch_name) |
49 |
| - fqbn = "arduino:avr:uno" |
50 |
| - |
51 |
| - # Create a test sketch |
52 |
| - result = run_command("sketch new {}".format(sketch_path)) |
53 |
| - assert result.ok |
54 |
| - assert "Sketch created in: {}".format(sketch_path) in result.stdout |
55 |
| - |
56 |
| - # Build sketch for arduino:avr:uno |
57 |
| - log_file_name = "compile.log" |
58 |
| - log_file_path = os.path.join(data_dir, log_file_name) |
59 |
| - result = run_command( |
60 |
| - "compile -b {fqbn} {sketch_path} --log-format json --log-file {log_file} --log-level trace".format( |
61 |
| - fqbn=fqbn, sketch_path=sketch_path, log_file=log_file_path |
62 |
| - ) |
63 |
| - ) |
64 |
| - assert result.ok |
65 |
| - |
66 |
| - # let's test from the logs if the hex file produced by successful compile is moved to our sketch folder |
67 |
| - log_json = open(log_file_path, "r") |
68 |
| - json_log_lines = log_json.readlines() |
69 |
| - expected_trace_sequence = [ |
70 |
| - "Compile {sketch} for {fqbn} started".format(sketch=sketch_path, fqbn=fqbn), |
71 |
| - "Compile {sketch} for {fqbn} successful".format(sketch=sketch_name, fqbn=fqbn), |
72 |
| - ] |
73 |
| - assert is_message_sequence_in_json_log_traces( |
74 |
| - expected_trace_sequence, json_log_lines |
75 |
| - ) |
76 |
| - |
77 |
| - # Test the --output flag with absolute path |
78 |
| - target = os.path.join(data_dir, "test.hex") |
79 |
| - result = run_command( |
80 |
| - "compile -b {fqbn} {sketch_path} -o {target}".format( |
81 |
| - fqbn=fqbn, sketch_path=sketch_path, target=target |
82 |
| - ) |
83 |
| - ) |
84 |
| - assert result.ok |
85 |
| - assert os.path.exists(target) |
86 |
| - |
87 |
| - |
88 |
| -@pytest.mark.skipif( |
89 |
| - running_on_ci() and platform.system() == "Windows", |
90 |
| - reason="Test disabled on Github Actions Win VM until tmpdir inconsistent behavior bug is fixed", |
91 |
| -) |
92 |
| -def test_output_flag_default_path(run_command, data_dir, working_dir): |
93 |
| - # Init the environment explicitly |
94 |
| - result = run_command("core update-index") |
95 |
| - assert result.ok |
96 |
| - |
97 |
| - # Download latest AVR |
98 |
| - result = run_command("core install arduino:avr") |
99 |
| - assert result.ok |
100 |
| - |
101 |
| - # Create a test sketch |
102 |
| - sketch_path = os.path.join(data_dir, "test_output_flag_default_path") |
103 |
| - fqbn = "arduino:avr:uno" |
104 |
| - result = run_command("sketch new {}".format(sketch_path)) |
105 |
| - assert result.ok |
106 |
| - |
107 |
| - # Test the --output flag defaulting to current working dir |
108 |
| - result = run_command( |
109 |
| - "compile -b {fqbn} {sketch_path} -o test".format( |
110 |
| - fqbn=fqbn, sketch_path=sketch_path |
111 |
| - ) |
112 |
| - ) |
113 |
| - assert result.ok |
114 |
| - assert os.path.exists(os.path.join(working_dir, "test.hex")) |
115 |
| - |
116 |
| - # Test extension won't be added if already present |
117 |
| - result = run_command( |
118 |
| - "compile -b {fqbn} {sketch_path} -o test2.hex".format( |
119 |
| - fqbn=fqbn, sketch_path=sketch_path |
120 |
| - ) |
121 |
| - ) |
122 |
| - assert result.ok |
123 |
| - assert os.path.exists(os.path.join(working_dir, "test2.hex")) |
124 |
| - |
125 |
| - |
126 |
| -def test_compile_with_sketch_with_symlink_selfloop(run_command, data_dir): |
127 |
| - # Init the environment explicitly |
128 |
| - result = run_command("core update-index") |
129 |
| - assert result.ok |
130 |
| - |
131 |
| - # Download latest AVR |
132 |
| - result = run_command("core install arduino:avr") |
133 |
| - assert result.ok |
134 |
| - |
135 |
| - sketch_name = "CompileIntegrationTestSymlinkSelfLoop" |
136 |
| - sketch_path = os.path.join(data_dir, sketch_name) |
137 |
| - fqbn = "arduino:avr:uno" |
138 |
| - |
139 |
| - # Create a test sketch |
140 |
| - result = run_command("sketch new {}".format(sketch_path)) |
141 |
| - assert result.ok |
142 |
| - assert "Sketch created in: {}".format(sketch_path) in result.stdout |
143 |
| - |
144 |
| - # create a symlink that loops on himself |
145 |
| - loop_file_path = os.path.join(sketch_path, "loop") |
146 |
| - os.symlink(loop_file_path, loop_file_path) |
147 |
| - |
148 |
| - # Build sketch for arduino:avr:uno |
149 |
| - result = run_command( |
150 |
| - "compile -b {fqbn} {sketch_path}".format(fqbn=fqbn, sketch_path=sketch_path) |
151 |
| - ) |
152 |
| - # The assertion is a bit relaxed in this case because win behaves differently from macOs and linux |
153 |
| - # returning a different error detailed message |
154 |
| - assert "Error during sketch processing" in result.stderr |
155 |
| - assert not result.ok |
156 |
| - |
157 |
| - sketch_name = "CompileIntegrationTestSymlinkDirLoop" |
158 |
| - sketch_path = os.path.join(data_dir, sketch_name) |
159 |
| - fqbn = "arduino:avr:uno" |
160 |
| - |
161 |
| - # Create a test sketch |
162 |
| - result = run_command("sketch new {}".format(sketch_path)) |
163 |
| - assert result.ok |
164 |
| - assert "Sketch created in: {}".format(sketch_path) in result.stdout |
165 |
| - |
166 |
| - # create a symlink that loops on the upper level |
167 |
| - loop_dir_path = os.path.join(sketch_path, "loop_dir") |
168 |
| - os.mkdir(loop_dir_path) |
169 |
| - loop_dir_symlink_path = os.path.join(loop_dir_path, "loop_dir_symlink") |
170 |
| - os.symlink(loop_dir_path, loop_dir_symlink_path) |
171 |
| - |
172 |
| - # Build sketch for arduino:avr:uno |
173 |
| - result = run_command( |
174 |
| - "compile -b {fqbn} {sketch_path}".format(fqbn=fqbn, sketch_path=sketch_path) |
175 |
| - ) |
176 |
| - # The assertion is a bit relaxed also in this case because macOS behaves differently from win and linux: |
177 |
| - # the cli does not follow recursively the symlink til breaking |
178 |
| - assert "Error during sketch processing" in result.stderr |
179 |
| - assert not result.ok |
180 |
| - |
181 |
| - |
182 |
| -@pytest.mark.skipif(running_on_ci(), reason="VMs have no serial ports") |
183 |
| -def test_compile_and_compile_combo(run_command, data_dir, detected_boards): |
184 |
| - # Init the environment explicitly |
185 |
| - result = run_command("core update-index") |
186 |
| - assert result.ok |
187 |
| - |
188 |
| - # Install required core(s) |
189 |
| - result = run_command("core install arduino:avr") |
190 |
| - result = run_command("core install arduino:samd") |
191 |
| - assert result.ok |
192 |
| - |
193 |
| - # Create a test sketch |
194 |
| - sketch_name = "CompileAndUploadIntegrationTest" |
195 |
| - sketch_path = os.path.join(data_dir, sketch_name) |
196 |
| - result = run_command("sketch new {}".format(sketch_path)) |
197 |
| - assert result.ok |
198 |
| - assert "Sketch created in: {}".format(sketch_path) in result.stdout |
199 |
| - |
200 |
| - # Build sketch for each detected board |
201 |
| - for board in detected_boards: |
202 |
| - log_file_name = "{fqbn}-compile.log".format(fqbn=board.fqbn.replace(":", "-")) |
203 |
| - log_file_path = os.path.join(data_dir, log_file_name) |
204 |
| - command_log_flags = "--log-format json --log-file {} --log-level trace".format( |
205 |
| - log_file_path |
206 |
| - ) |
207 |
| - result = run_command( |
208 |
| - "compile -b {fqbn} --upload -p {address} {sketch_path} {log_flags}".format( |
209 |
| - fqbn=board.fqbn, |
210 |
| - address=board.address, |
211 |
| - sketch_path=sketch_path, |
212 |
| - log_flags=command_log_flags, |
213 |
| - ) |
214 |
| - ) |
215 |
| - assert result.ok |
216 |
| - # check from the logs if the bin file were uploaded on the current board |
217 |
| - log_json = open(log_file_path, "r") |
218 |
| - json_log_lines = log_json.readlines() |
219 |
| - expected_trace_sequence = [ |
220 |
| - "Compile {sketch} for {fqbn} started".format( |
221 |
| - sketch=sketch_path, fqbn=board.fqbn |
222 |
| - ), |
223 |
| - "Compile {sketch} for {fqbn} successful".format( |
224 |
| - sketch=sketch_name, fqbn=board.fqbn |
225 |
| - ), |
226 |
| - "Upload {sketch} on {fqbn} started".format( |
227 |
| - sketch=sketch_path, fqbn=board.fqbn |
228 |
| - ), |
229 |
| - "Upload {sketch} on {fqbn} successful".format( |
230 |
| - sketch=sketch_name, fqbn=board.fqbn |
231 |
| - ), |
232 |
| - ] |
233 |
| - assert is_message_sequence_in_json_log_traces( |
234 |
| - expected_trace_sequence, json_log_lines |
235 |
| - ) |
236 | 15 |
|
| 16 | +import os |
| 17 | +import subprocess |
| 18 | +import time |
237 | 19 |
|
238 |
| -def is_message_sequence_in_json_log_traces(message_sequence, log_json_lines): |
239 |
| - trace_entries = [] |
240 |
| - for entry in log_json_lines: |
241 |
| - entry = json.loads(entry) |
242 |
| - if entry.get("level") == "trace": |
243 |
| - if entry.get("msg") in message_sequence: |
244 |
| - trace_entries.append(entry.get("msg")) |
245 |
| - return message_sequence == trace_entries |
| 20 | +import requests |
| 21 | +import yaml |
| 22 | +from prometheus_client.parser import text_string_to_metric_families |
246 | 23 |
|
247 | 24 |
|
248 |
| -def test_compile_blacklisted_sketchname(run_command, data_dir): |
249 |
| - """ |
250 |
| - Compile should ignore folders named `RCS`, `.git` and the likes, but |
251 |
| - it should be ok for a sketch to be named like RCS.ino |
252 |
| - """ |
| 25 | +def test_telemetry_prometheus_endpoint(pytestconfig, data_dir, downloads_dir): |
253 | 26 | # Init the environment explicitly
|
254 |
| - result = run_command("core update-index") |
255 |
| - assert result.ok |
256 |
| - |
257 |
| - # Download latest AVR |
258 |
| - result = run_command("core install arduino:avr") |
259 |
| - assert result.ok |
260 |
| - |
261 |
| - sketch_name = "RCS" |
262 |
| - sketch_path = os.path.join(data_dir, sketch_name) |
263 |
| - fqbn = "arduino:avr:uno" |
264 |
| - |
265 |
| - # Create a test sketch |
266 |
| - result = run_command("sketch new {}".format(sketch_path)) |
267 |
| - assert result.ok |
268 |
| - assert "Sketch created in: {}".format(sketch_path) in result.stdout |
269 |
| - |
270 |
| - # Build sketch for arduino:avr:uno |
271 |
| - log_file_name = "compile.log" |
272 |
| - log_file_path = os.path.join(data_dir, log_file_name) |
273 |
| - result = run_command( |
274 |
| - "compile -b {fqbn} {sketch_path}".format(fqbn=fqbn, sketch_path=sketch_path) |
275 |
| - ) |
276 |
| - assert result.ok |
| 27 | + cli_path = os.path.join(str(pytestconfig.rootdir), "..", "arduino-cli") |
| 28 | + env = os.environ.copy() |
| 29 | + env["ARDUINO_DATA_DIR"] = data_dir |
| 30 | + env["ARDUINO_DOWNLOADS_DIR"] = downloads_dir |
| 31 | + env["ARDUINO_SKETCHBOOK_DIR"] = data_dir |
| 32 | + |
| 33 | + subprocess.Popen([cli_path, "daemon"], env=env) |
| 34 | + |
| 35 | + time.sleep(5) |
| 36 | + |
| 37 | + # parse repertory file |
| 38 | + repertory_file = os.path.join(data_dir, "repertory.yaml") |
| 39 | + with open(repertory_file, 'r') as stream: |
| 40 | + repertory = yaml.safe_load(stream) |
| 41 | + |
| 42 | + # Check if :9090/metrics endpoint is alive, |
| 43 | + # telemetry is enabled by default in daemon mode |
| 44 | + metrics = requests.get("http://localhost:9090/metrics").text |
| 45 | + family = next(text_string_to_metric_families(metrics)) |
| 46 | + sample = family.samples[0] |
| 47 | + assert repertory["installation"]["id"] == sample.labels["installationID"] |
0 commit comments