rbx.cp 0.8.0__py3-none-any.whl → 0.9.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rbx/box/cd.py +2 -2
- rbx/box/cli.py +11 -2
- rbx/box/code.py +2 -2
- rbx/box/contest/build_contest_statements.py +2 -2
- rbx/box/contest/contest_package.py +1 -1
- rbx/box/contest/main.py +29 -2
- rbx/box/environment.py +143 -83
- rbx/box/formatting.py +2 -1
- rbx/box/package.py +5 -5
- rbx/box/packaging/__init__.py +0 -0
- rbx/box/packaging/boca/__init__.py +0 -0
- rbx/box/packaging/polygon/packager.py +3 -3
- rbx/box/presets/__init__.py +369 -53
- rbx/box/presets/lock_schema.py +42 -2
- rbx/box/presets/schema.py +4 -0
- rbx/box/remote.py +3 -3
- rbx/box/retries.py +3 -2
- rbx/box/sanitizers/warning_stack.py +2 -2
- rbx/box/setter_config.py +18 -0
- rbx/box/solutions.py +24 -18
- rbx/box/statements/build_statements.py +6 -6
- rbx/box/statements/builders.py +1 -1
- rbx/box/stresses.py +2 -2
- rbx/box/testcase_utils.py +3 -3
- rbx/config.py +7 -0
- rbx/grading/caching.py +24 -2
- rbx/grading/conftest.py +2 -2
- rbx/grading/grading_context.py +25 -0
- rbx/grading/judge/sandbox.py +2 -1
- rbx/grading/judge/sandboxes/isolate.py +3 -2
- rbx/grading/judge/sandboxes/stupid_sandbox.py +3 -2
- rbx/grading/judge/storage.py +2 -1
- rbx/grading/steps.py +2 -1
- rbx/grading/steps_with_caching_run_test.py +281 -5
- rbx/resources/default_setter_config.mac.yml +15 -0
- rbx/resources/default_setter_config.yml +15 -0
- rbx/resources/envs/default.rbx.yml +43 -13
- rbx/resources/envs/isolate.rbx.yml +2 -3
- rbx/resources/presets/default/contest/.gitignore +5 -1
- rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -1
- rbx/resources/presets/default/env.rbx.yml +67 -0
- rbx/resources/presets/default/preset.rbx.yml +6 -2
- rbx/resources/presets/default/problem/.gitignore +1 -1
- rbx/resources/presets/default/{contest/statement/template.rbx.tex → shared/problem_template.rbx.tex} +13 -7
- rbx/submitors/codeforces.py +3 -2
- rbx/test.py +1 -1
- rbx/utils.py +6 -1
- {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.1.dist-info}/METADATA +2 -1
- {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.1.dist-info}/RECORD +54 -52
- rbx/resources/presets/default/problem/statement/icpc.sty +0 -322
- /rbx/resources/presets/default/{problem/statement/template.rbx.tex → shared/contest_template.rbx.tex} +0 -0
- /rbx/resources/presets/default/{contest/statement → shared}/icpc.sty +0 -0
- {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.1.dist-info}/LICENSE +0 -0
- {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.1.dist-info}/WHEEL +0 -0
- {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.1.dist-info}/entry_points.txt +0 -0
@@ -2,9 +2,12 @@ import os
|
|
2
2
|
import pathlib
|
3
3
|
import sys
|
4
4
|
|
5
|
-
|
5
|
+
import pytest
|
6
|
+
|
7
|
+
from rbx.grading import grading_context, steps_with_caching
|
6
8
|
from rbx.grading.caching import DependencyCache
|
7
9
|
from rbx.grading.judge.cacher import FileCacher
|
10
|
+
from rbx.grading.judge.digester import digest_cooperatively
|
8
11
|
from rbx.grading.judge.sandbox import SandboxBase, SandboxParams
|
9
12
|
from rbx.grading.steps import (
|
10
13
|
DigestOrSource,
|
@@ -74,6 +77,124 @@ async def test_run_from_disk(
|
|
74
77
|
assert not artifacts.logs.cached
|
75
78
|
|
76
79
|
|
80
|
+
async def test_run_reruns_if_cache_disabled(
|
81
|
+
cleandir: pathlib.Path,
|
82
|
+
dependency_cache: DependencyCache,
|
83
|
+
sandbox: SandboxBase,
|
84
|
+
file_cacher: FileCacher,
|
85
|
+
):
|
86
|
+
async def configure_and_run_with_dest(dest: pathlib.Path) -> GradingArtifacts:
|
87
|
+
executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
|
88
|
+
artifacts = GradingArtifacts()
|
89
|
+
artifacts.inputs.append(
|
90
|
+
GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
|
91
|
+
)
|
92
|
+
artifacts.outputs.append(
|
93
|
+
GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
|
94
|
+
)
|
95
|
+
with grading_context.cache_level(grading_context.CacheLevel.NO_CACHE):
|
96
|
+
await steps_with_caching.run(
|
97
|
+
f'{sys.executable} executable.py',
|
98
|
+
params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
|
99
|
+
sandbox=sandbox,
|
100
|
+
artifacts=artifacts,
|
101
|
+
dependency_cache=dependency_cache,
|
102
|
+
)
|
103
|
+
return artifacts
|
104
|
+
|
105
|
+
artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
106
|
+
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
107
|
+
assert artifacts.logs is not None
|
108
|
+
assert not artifacts.logs.cached
|
109
|
+
|
110
|
+
another_artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
111
|
+
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
112
|
+
assert another_artifacts.logs is not None
|
113
|
+
assert not another_artifacts.logs.cached
|
114
|
+
|
115
|
+
|
116
|
+
async def test_run_reruns_if_first_run_cache_disabled(
|
117
|
+
cleandir: pathlib.Path,
|
118
|
+
dependency_cache: DependencyCache,
|
119
|
+
sandbox: SandboxBase,
|
120
|
+
file_cacher: FileCacher,
|
121
|
+
):
|
122
|
+
async def configure_and_run_with_dest(
|
123
|
+
dest: pathlib.Path, cache: bool = True
|
124
|
+
) -> GradingArtifacts:
|
125
|
+
executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
|
126
|
+
artifacts = GradingArtifacts()
|
127
|
+
artifacts.inputs.append(
|
128
|
+
GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
|
129
|
+
)
|
130
|
+
artifacts.outputs.append(
|
131
|
+
GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
|
132
|
+
)
|
133
|
+
with grading_context.cache_level(
|
134
|
+
grading_context.CacheLevel.NO_CACHE, when=cache
|
135
|
+
):
|
136
|
+
await steps_with_caching.run(
|
137
|
+
f'{sys.executable} executable.py',
|
138
|
+
params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
|
139
|
+
sandbox=sandbox,
|
140
|
+
artifacts=artifacts,
|
141
|
+
dependency_cache=dependency_cache,
|
142
|
+
)
|
143
|
+
return artifacts
|
144
|
+
|
145
|
+
artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'), cache=False)
|
146
|
+
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
147
|
+
assert artifacts.logs is not None
|
148
|
+
assert not artifacts.logs.cached
|
149
|
+
|
150
|
+
another_artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
151
|
+
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
152
|
+
assert another_artifacts.logs is not None
|
153
|
+
assert not another_artifacts.logs.cached
|
154
|
+
|
155
|
+
|
156
|
+
async def test_run_reruns_if_second_run_cache_disabled(
|
157
|
+
cleandir: pathlib.Path,
|
158
|
+
dependency_cache: DependencyCache,
|
159
|
+
sandbox: SandboxBase,
|
160
|
+
file_cacher: FileCacher,
|
161
|
+
):
|
162
|
+
async def configure_and_run_with_dest(
|
163
|
+
dest: pathlib.Path, cache: bool = True
|
164
|
+
) -> GradingArtifacts:
|
165
|
+
executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
|
166
|
+
artifacts = GradingArtifacts()
|
167
|
+
artifacts.inputs.append(
|
168
|
+
GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
|
169
|
+
)
|
170
|
+
artifacts.outputs.append(
|
171
|
+
GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
|
172
|
+
)
|
173
|
+
with grading_context.cache_level(
|
174
|
+
grading_context.CacheLevel.NO_CACHE, when=cache
|
175
|
+
):
|
176
|
+
await steps_with_caching.run(
|
177
|
+
f'{sys.executable} executable.py',
|
178
|
+
params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
|
179
|
+
sandbox=sandbox,
|
180
|
+
artifacts=artifacts,
|
181
|
+
dependency_cache=dependency_cache,
|
182
|
+
)
|
183
|
+
return artifacts
|
184
|
+
|
185
|
+
artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
186
|
+
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
187
|
+
assert artifacts.logs is not None
|
188
|
+
assert not artifacts.logs.cached
|
189
|
+
|
190
|
+
another_artifacts = await configure_and_run_with_dest(
|
191
|
+
pathlib.Path('out.txt'), cache=False
|
192
|
+
)
|
193
|
+
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
194
|
+
assert another_artifacts.logs is not None
|
195
|
+
assert not another_artifacts.logs.cached
|
196
|
+
|
197
|
+
|
77
198
|
async def test_run_caches_intermediate_digest_if_dest_changes(
|
78
199
|
cleandir: pathlib.Path,
|
79
200
|
dependency_cache: DependencyCache,
|
@@ -106,12 +227,127 @@ async def test_run_caches_intermediate_digest_if_dest_changes(
|
|
106
227
|
another_artifacts = await configure_and_run_with_dest(
|
107
228
|
pathlib.Path('another-out.txt')
|
108
229
|
)
|
230
|
+
assert (cleandir / 'another-out.txt').read_text().strip() == '5'
|
231
|
+
assert another_artifacts.logs is not None
|
232
|
+
assert another_artifacts.logs.cached
|
233
|
+
|
234
|
+
|
235
|
+
async def test_run_caches_intermediate_digest_if_dest_changes_and_cache_transient(
|
236
|
+
cleandir: pathlib.Path,
|
237
|
+
dependency_cache: DependencyCache,
|
238
|
+
sandbox: SandboxBase,
|
239
|
+
file_cacher: FileCacher,
|
240
|
+
):
|
241
|
+
async def configure_and_run_with_dest(dest: pathlib.Path) -> GradingArtifacts:
|
242
|
+
executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
|
243
|
+
artifacts = GradingArtifacts()
|
244
|
+
artifacts.inputs.append(
|
245
|
+
GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
|
246
|
+
)
|
247
|
+
artifacts.outputs.append(
|
248
|
+
GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
|
249
|
+
)
|
250
|
+
|
251
|
+
with grading_context.cache_level(grading_context.CacheLevel.CACHE_TRANSIENTLY):
|
252
|
+
await steps_with_caching.run(
|
253
|
+
f'{sys.executable} executable.py',
|
254
|
+
params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
|
255
|
+
sandbox=sandbox,
|
256
|
+
artifacts=artifacts,
|
257
|
+
dependency_cache=dependency_cache,
|
258
|
+
)
|
259
|
+
return artifacts
|
260
|
+
|
261
|
+
artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
262
|
+
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
263
|
+
assert artifacts.logs is not None
|
264
|
+
assert not artifacts.logs.cached
|
265
|
+
|
266
|
+
another_artifacts = await configure_and_run_with_dest(
|
267
|
+
pathlib.Path('another-out.txt')
|
268
|
+
)
|
269
|
+
assert (cleandir / 'another-out.txt').read_text().strip() == '5'
|
270
|
+
assert another_artifacts.logs is not None
|
271
|
+
assert another_artifacts.logs.cached
|
272
|
+
|
273
|
+
|
274
|
+
async def test_run_overwrites_changed_file_when_storage_value_is_changed_and_cache_transient(
|
275
|
+
cleandir: pathlib.Path,
|
276
|
+
dependency_cache: DependencyCache,
|
277
|
+
sandbox: SandboxBase,
|
278
|
+
file_cacher: FileCacher,
|
279
|
+
):
|
280
|
+
async def configure_and_run_with_dest(dest: pathlib.Path) -> GradingArtifacts:
|
281
|
+
executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
|
282
|
+
artifacts = GradingArtifacts()
|
283
|
+
artifacts.inputs.append(
|
284
|
+
GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
|
285
|
+
)
|
286
|
+
artifacts.outputs.append(
|
287
|
+
GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
|
288
|
+
)
|
289
|
+
with grading_context.cache_level(grading_context.CacheLevel.CACHE_TRANSIENTLY):
|
290
|
+
await steps_with_caching.run(
|
291
|
+
f'{sys.executable} executable.py',
|
292
|
+
params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
|
293
|
+
sandbox=sandbox,
|
294
|
+
artifacts=artifacts,
|
295
|
+
dependency_cache=dependency_cache,
|
296
|
+
)
|
297
|
+
return artifacts
|
298
|
+
|
299
|
+
artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
300
|
+
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
301
|
+
assert artifacts.logs is not None
|
302
|
+
assert not artifacts.logs.cached
|
303
|
+
|
304
|
+
pathlib.Path('out.txt').write_text('42')
|
305
|
+
|
306
|
+
another_artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
307
|
+
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
308
|
+
assert another_artifacts.logs is not None
|
309
|
+
assert another_artifacts.logs.cached
|
310
|
+
|
311
|
+
|
312
|
+
async def test_run_overwrites_changed_file_when_file_deleted_and_cache_transient(
|
313
|
+
cleandir: pathlib.Path,
|
314
|
+
dependency_cache: DependencyCache,
|
315
|
+
sandbox: SandboxBase,
|
316
|
+
file_cacher: FileCacher,
|
317
|
+
):
|
318
|
+
async def configure_and_run_with_dest(dest: pathlib.Path) -> GradingArtifacts:
|
319
|
+
executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
|
320
|
+
artifacts = GradingArtifacts()
|
321
|
+
artifacts.inputs.append(
|
322
|
+
GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
|
323
|
+
)
|
324
|
+
artifacts.outputs.append(
|
325
|
+
GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
|
326
|
+
)
|
327
|
+
with grading_context.cache_level(grading_context.CacheLevel.CACHE_TRANSIENTLY):
|
328
|
+
await steps_with_caching.run(
|
329
|
+
f'{sys.executable} executable.py',
|
330
|
+
params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
|
331
|
+
sandbox=sandbox,
|
332
|
+
artifacts=artifacts,
|
333
|
+
dependency_cache=dependency_cache,
|
334
|
+
)
|
335
|
+
return artifacts
|
336
|
+
|
337
|
+
artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
338
|
+
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
339
|
+
assert artifacts.logs is not None
|
340
|
+
assert not artifacts.logs.cached
|
341
|
+
|
342
|
+
pathlib.Path('out.txt').unlink()
|
343
|
+
|
344
|
+
another_artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
109
345
|
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
110
346
|
assert another_artifacts.logs is not None
|
111
347
|
assert another_artifacts.logs.cached
|
112
348
|
|
113
349
|
|
114
|
-
async def
|
350
|
+
async def test_run_fails_when_storage_value_is_changed_and_integrity_check_is_enabled(
|
115
351
|
cleandir: pathlib.Path,
|
116
352
|
dependency_cache: DependencyCache,
|
117
353
|
sandbox: SandboxBase,
|
@@ -142,13 +378,50 @@ async def test_run_overwrite_changed_file_with_storage_value(
|
|
142
378
|
|
143
379
|
pathlib.Path('out.txt').write_text('42')
|
144
380
|
|
381
|
+
with pytest.raises(ValueError) as exc_info:
|
382
|
+
await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
383
|
+
assert 'rbx clean' in str(exc_info.value)
|
384
|
+
assert (cleandir / 'out.txt').read_text().strip() == '42'
|
385
|
+
|
386
|
+
|
387
|
+
async def test_run_evicts_and_recreates_deleted_file_with_storage_value(
|
388
|
+
cleandir: pathlib.Path,
|
389
|
+
dependency_cache: DependencyCache,
|
390
|
+
sandbox: SandboxBase,
|
391
|
+
file_cacher: FileCacher,
|
392
|
+
):
|
393
|
+
async def configure_and_run_with_dest(dest: pathlib.Path) -> GradingArtifacts:
|
394
|
+
executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
|
395
|
+
artifacts = GradingArtifacts()
|
396
|
+
artifacts.inputs.append(
|
397
|
+
GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
|
398
|
+
)
|
399
|
+
artifacts.outputs.append(
|
400
|
+
GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
|
401
|
+
)
|
402
|
+
await steps_with_caching.run(
|
403
|
+
f'{sys.executable} executable.py',
|
404
|
+
params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
|
405
|
+
sandbox=sandbox,
|
406
|
+
artifacts=artifacts,
|
407
|
+
dependency_cache=dependency_cache,
|
408
|
+
)
|
409
|
+
return artifacts
|
410
|
+
|
411
|
+
artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
412
|
+
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
413
|
+
assert artifacts.logs is not None
|
414
|
+
assert not artifacts.logs.cached
|
415
|
+
|
416
|
+
pathlib.Path('out.txt').unlink()
|
417
|
+
|
145
418
|
another_artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
146
419
|
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
147
420
|
assert another_artifacts.logs is not None
|
148
421
|
assert another_artifacts.logs.cached
|
149
422
|
|
150
423
|
|
151
|
-
async def
|
424
|
+
async def test_run_evicts_when_storage_value_deleted(
|
152
425
|
cleandir: pathlib.Path,
|
153
426
|
dependency_cache: DependencyCache,
|
154
427
|
sandbox: SandboxBase,
|
@@ -177,12 +450,15 @@ async def test_run_recreates_deleted_file_with_storage_value(
|
|
177
450
|
assert artifacts.logs is not None
|
178
451
|
assert not artifacts.logs.cached
|
179
452
|
|
180
|
-
|
453
|
+
# Delete the file from the cache
|
454
|
+
with pathlib.Path('out.txt').open('rb') as f:
|
455
|
+
digest = digest_cooperatively(f)
|
456
|
+
file_cacher.delete(digest)
|
181
457
|
|
182
458
|
another_artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
|
183
459
|
assert (cleandir / 'out.txt').read_text().strip() == '5'
|
184
460
|
assert another_artifacts.logs is not None
|
185
|
-
assert another_artifacts.logs.cached
|
461
|
+
assert not another_artifacts.logs.cached
|
186
462
|
|
187
463
|
|
188
464
|
async def test_run_overwrite_exec_bit_when_changed(
|
@@ -14,6 +14,21 @@ command_substitutions:
|
|
14
14
|
python2: python2
|
15
15
|
python3: python3
|
16
16
|
|
17
|
+
caching:
|
18
|
+
# Set the caching level.
|
19
|
+
#
|
20
|
+
# CACHE_ALL: Cache everything.
|
21
|
+
# CACHE_COMPILATION: Cache only compilation.
|
22
|
+
# NO_CACHE: Do not cache anything.
|
23
|
+
level: CACHE_ALL
|
24
|
+
|
25
|
+
# Whether to check the integrity of the cached result, and evict it
|
26
|
+
# if file has changed since it was cached.
|
27
|
+
#
|
28
|
+
# Disable for more performance, but be careful to not modify any generated
|
29
|
+
# files.
|
30
|
+
check_integrity: true
|
31
|
+
|
17
32
|
repeats:
|
18
33
|
# Number of times to run the solution.
|
19
34
|
reps: 1
|
@@ -14,6 +14,21 @@ command_substitutions:
|
|
14
14
|
python2: python2
|
15
15
|
python3: python3
|
16
16
|
|
17
|
+
caching:
|
18
|
+
# Set the caching level.
|
19
|
+
#
|
20
|
+
# CACHE_ALL: Cache everything.
|
21
|
+
# CACHE_COMPILATION: Cache only compilation.
|
22
|
+
# NO_CACHE: Do not cache anything.
|
23
|
+
level: CACHE_ALL
|
24
|
+
|
25
|
+
# Whether to check the integrity of the cached result, and evict it
|
26
|
+
# if file has changed since it was cached.
|
27
|
+
#
|
28
|
+
# Disable for more performance, but be careful to not modify any generated
|
29
|
+
# files.
|
30
|
+
check_integrity: true
|
31
|
+
|
17
32
|
repeats:
|
18
33
|
# Number of times to run the solution.
|
19
34
|
reps: 1
|
@@ -3,35 +3,65 @@ sandbox: "stupid"
|
|
3
3
|
defaultCompilation:
|
4
4
|
sandbox:
|
5
5
|
maxProcesses: 1000
|
6
|
-
timeLimit:
|
7
|
-
wallTimeLimit:
|
6
|
+
timeLimit: 50000 # 50 seconds
|
7
|
+
wallTimeLimit: 50000 # 50 seconds
|
8
8
|
memoryLimit: 1024 # 1gb
|
9
|
-
preserveEnv: true
|
10
|
-
mirrorDirs:
|
11
|
-
- "/etc"
|
12
|
-
- "/usr"
|
13
9
|
defaultExecution:
|
14
10
|
sandbox:
|
15
11
|
# Useful for checkers, validators, etc.
|
16
|
-
timeLimit:
|
17
|
-
wallTimeLimit:
|
12
|
+
timeLimit: 50000 # 50 seconds
|
13
|
+
wallTimeLimit: 50000 # 50 seconds
|
18
14
|
memoryLimit: 1024 # 1gb
|
19
15
|
languages:
|
20
16
|
- name: "cpp"
|
21
|
-
|
17
|
+
readableName: "C++20"
|
22
18
|
extension: "cpp"
|
23
19
|
compilation:
|
24
|
-
commands:
|
25
|
-
- "g++ -std=c++17 -O2 -o {executable} {compilable}"
|
20
|
+
commands: ["g++ -std=c++20 -O2 -o {executable} {compilable}"]
|
26
21
|
execution:
|
27
22
|
command: "./{executable}"
|
28
23
|
fileMapping:
|
29
24
|
compilable: "compilable.cpp"
|
25
|
+
extensions:
|
26
|
+
boca:
|
27
|
+
bocaLanguage: "cc"
|
28
|
+
- name: "c"
|
29
|
+
readableName: "C"
|
30
|
+
extension: "c"
|
31
|
+
compilation:
|
32
|
+
commands: ["gcc -std=gnu11 -O2 -lm -o {executable} {compilable}"]
|
33
|
+
execution:
|
34
|
+
command: "./{executable}"
|
35
|
+
fileMapping:
|
36
|
+
compilable: "compilable.c"
|
30
37
|
- name: "py"
|
31
|
-
|
38
|
+
readableName: "Python3"
|
32
39
|
extension: "py"
|
33
40
|
execution:
|
34
41
|
command: "python3 {executable}"
|
35
42
|
fileMapping:
|
36
43
|
executable: "executable.py"
|
37
|
-
|
44
|
+
extensions:
|
45
|
+
boca:
|
46
|
+
bocaLanguage: "py3"
|
47
|
+
- name: "java"
|
48
|
+
readableName: "Java"
|
49
|
+
extension: "java"
|
50
|
+
compilation:
|
51
|
+
commands:
|
52
|
+
- "javac -Xlint -encoding UTF-8 {compilable}"
|
53
|
+
- "jar cvf {executable} @glob:*.class"
|
54
|
+
execution:
|
55
|
+
command:
|
56
|
+
"java -Xss100m -Xmx{{memory}}m -Xms{{initialMemory}}m -cp {executable}
|
57
|
+
Main"
|
58
|
+
fileMapping:
|
59
|
+
compilable: "Main.java"
|
60
|
+
executable: "Main.jar"
|
61
|
+
extensions:
|
62
|
+
boca:
|
63
|
+
languages: ["c", "cc", "java", "py3"]
|
64
|
+
flags:
|
65
|
+
c: "-O2 -lm -static"
|
66
|
+
cc: "-std=c++20 -O2 -lm -static"
|
67
|
+
preferContestLetter: true
|
@@ -18,7 +18,7 @@ defaultExecution:
|
|
18
18
|
memoryLimit: 1024 # 1gb
|
19
19
|
languages:
|
20
20
|
- name: "cpp"
|
21
|
-
|
21
|
+
readableName: "C++17"
|
22
22
|
extension: "cpp"
|
23
23
|
compilation:
|
24
24
|
commands:
|
@@ -28,10 +28,9 @@ languages:
|
|
28
28
|
fileMapping:
|
29
29
|
compilable: "compilable.cpp"
|
30
30
|
- name: "py"
|
31
|
-
|
31
|
+
readableName: "Python3"
|
32
32
|
extension: "py"
|
33
33
|
execution:
|
34
34
|
command: "/usr/bin/python3 {executable}"
|
35
35
|
fileMapping:
|
36
36
|
executable: "executable.py"
|
37
|
-
|
@@ -0,0 +1,67 @@
|
|
1
|
+
---
|
2
|
+
sandbox: "stupid"
|
3
|
+
defaultCompilation:
|
4
|
+
sandbox:
|
5
|
+
maxProcesses: 1000
|
6
|
+
timeLimit: 50000 # 50 seconds
|
7
|
+
wallTimeLimit: 50000 # 50 seconds
|
8
|
+
memoryLimit: 1024 # 1gb
|
9
|
+
defaultExecution:
|
10
|
+
sandbox:
|
11
|
+
# Useful for checkers, validators, etc.
|
12
|
+
timeLimit: 50000 # 50 seconds
|
13
|
+
wallTimeLimit: 50000 # 50 seconds
|
14
|
+
memoryLimit: 1024 # 1gb
|
15
|
+
languages:
|
16
|
+
- name: "cpp"
|
17
|
+
readableName: "C++20"
|
18
|
+
extension: "cpp"
|
19
|
+
compilation:
|
20
|
+
commands: ["g++ -std=c++20 -O2 -o {executable} {compilable}"]
|
21
|
+
execution:
|
22
|
+
command: "./{executable}"
|
23
|
+
fileMapping:
|
24
|
+
compilable: "compilable.cpp"
|
25
|
+
extensions:
|
26
|
+
boca:
|
27
|
+
bocaLanguage: "cc"
|
28
|
+
- name: "c"
|
29
|
+
readableName: "C"
|
30
|
+
extension: "c"
|
31
|
+
compilation:
|
32
|
+
commands: ["gcc -std=gnu11 -O2 -lm -o {executable} {compilable}"]
|
33
|
+
execution:
|
34
|
+
command: "./{executable}"
|
35
|
+
fileMapping:
|
36
|
+
compilable: "compilable.c"
|
37
|
+
- name: "py"
|
38
|
+
readableName: "Python3"
|
39
|
+
extension: "py"
|
40
|
+
execution:
|
41
|
+
command: "python3 {executable}"
|
42
|
+
fileMapping:
|
43
|
+
executable: "executable.py"
|
44
|
+
extensions:
|
45
|
+
boca:
|
46
|
+
bocaLanguage: "py3"
|
47
|
+
- name: "java"
|
48
|
+
readableName: "Java"
|
49
|
+
extension: "java"
|
50
|
+
compilation:
|
51
|
+
commands:
|
52
|
+
- "javac -Xlint -encoding UTF-8 {compilable}"
|
53
|
+
- "jar cvf {executable} @glob:*.class"
|
54
|
+
execution:
|
55
|
+
command:
|
56
|
+
"java -Xss100m -Xmx{{memory}}m -Xms{{initialMemory}}m -cp {executable}
|
57
|
+
Main"
|
58
|
+
fileMapping:
|
59
|
+
compilable: "Main.java"
|
60
|
+
executable: "Main.jar"
|
61
|
+
extensions:
|
62
|
+
boca:
|
63
|
+
languages: ["c", "cc", "java", "py3"]
|
64
|
+
flags:
|
65
|
+
c: "-O2 -lm -static"
|
66
|
+
cc: "-std=c++20 -O2 -lm -static"
|
67
|
+
preferContestLetter: true
|
@@ -4,11 +4,15 @@ name: "default"
|
|
4
4
|
uri: "rsalesc/rbx/rbx/resources/presets/default"
|
5
5
|
problem: "problem"
|
6
6
|
contest: "contest"
|
7
|
+
env: "env.rbx.yml"
|
7
8
|
tracking:
|
8
9
|
problem:
|
9
|
-
- path: "
|
10
|
+
- path: ".gitignore"
|
10
11
|
- path: "statement/icpc.sty"
|
11
|
-
contest:
|
12
12
|
- path: "statement/template.rbx.tex"
|
13
|
+
contest:
|
14
|
+
- path: ".gitignore"
|
13
15
|
- path: "statement/icpc.sty"
|
16
|
+
- path: "statement/template.rbx.tex"
|
14
17
|
- path: "statement/contest.rbx.tex"
|
18
|
+
symlink: true
|
rbx/resources/presets/default/{contest/statement/template.rbx.tex → shared/problem_template.rbx.tex}
RENAMED
@@ -1,4 +1,14 @@
|
|
1
|
-
|
1
|
+
\documentclass[a4paper,11pt]{article}
|
2
|
+
|
3
|
+
\def\lang{\VAR{lang}}
|
4
|
+
\usepackage{icpc}
|
5
|
+
|
6
|
+
%- if problem.blocks.preamble is defined
|
7
|
+
\VAR{problem.blocks.preamble}
|
8
|
+
%- endif
|
9
|
+
|
10
|
+
\begin{document}
|
11
|
+
|
2
12
|
\includeProblem
|
3
13
|
%- if problem.short_name is defined
|
4
14
|
[\VAR{problem.short_name}]
|
@@ -39,13 +49,9 @@
|
|
39
49
|
%- endif
|
40
50
|
|
41
51
|
%- if problem.blocks.notes is defined
|
42
|
-
\subsection*{
|
52
|
+
\subsection*{Observações}
|
43
53
|
\VAR{problem.blocks.notes}
|
44
54
|
%- endif
|
45
55
|
}
|
46
|
-
|
56
|
+
\end{document}
|
47
57
|
|
48
|
-
%- if problem.blocks.editorial is nonnull and vars.editorial is truthy
|
49
|
-
\subsection*{\strSolution}
|
50
|
-
\VAR{problem.blocks.editorial}
|
51
|
-
%- endif
|
rbx/submitors/codeforces.py
CHANGED
@@ -3,6 +3,7 @@ from typing import Any
|
|
3
3
|
|
4
4
|
import mechanize
|
5
5
|
|
6
|
+
from rbx import utils
|
6
7
|
from rbx.console import console
|
7
8
|
from rbx.schema import Problem
|
8
9
|
from rbx.submitors.submitor import Submitor
|
@@ -55,7 +56,7 @@ class Session:
|
|
55
56
|
)
|
56
57
|
|
57
58
|
def submit_from_contest(self, url: str, file: pathlib.Path, typeid: int):
|
58
|
-
filename = str(
|
59
|
+
filename = str(utils.abspath(file))
|
59
60
|
self.br.open(url)
|
60
61
|
form = self.select_form_by_class('submit-form', self.br.forms())
|
61
62
|
if form is None:
|
@@ -67,7 +68,7 @@ class Session:
|
|
67
68
|
self.br.submit()
|
68
69
|
|
69
70
|
def submit(self, url: str, file: pathlib.Path, typeid: int):
|
70
|
-
filename = str(
|
71
|
+
filename = str(utils.abspath(file))
|
71
72
|
response = self.br.open(url)
|
72
73
|
if response is None:
|
73
74
|
raise Exception('Response was not received')
|
rbx/test.py
CHANGED
@@ -159,7 +159,7 @@ def _pretty_print_outcome_panel(
|
|
159
159
|
) -> Panel:
|
160
160
|
result: steps.CheckerResult = eval.result
|
161
161
|
is_tle = result.outcome.is_slow() or (
|
162
|
-
problem.timeLimit and eval.log.time * 1000 > problem.timeLimit
|
162
|
+
problem.timeLimit and (eval.log.time or 0) * 1000 > problem.timeLimit
|
163
163
|
)
|
164
164
|
|
165
165
|
text = Text()
|
rbx/utils.py
CHANGED
@@ -3,6 +3,7 @@ import fcntl
|
|
3
3
|
import functools
|
4
4
|
import json
|
5
5
|
import os
|
6
|
+
import os.path
|
6
7
|
import pathlib
|
7
8
|
import resource
|
8
9
|
from typing import Any, Optional, Type, TypeVar
|
@@ -34,6 +35,10 @@ def highlight_str(s: str) -> text.Text:
|
|
34
35
|
return txt
|
35
36
|
|
36
37
|
|
38
|
+
def abspath(path: pathlib.Path) -> pathlib.Path:
|
39
|
+
return pathlib.Path(os.path.abspath(path))
|
40
|
+
|
41
|
+
|
37
42
|
def highlight_json_obj(obj: Any) -> text.Text:
|
38
43
|
js = json.dumps(obj)
|
39
44
|
return highlight_str(js)
|
@@ -70,7 +75,7 @@ def dump_schema(model: Type[BaseModel], path: pathlib.Path):
|
|
70
75
|
def ensure_schema(model: Type[BaseModel]) -> pathlib.Path:
|
71
76
|
path = get_app_path() / 'schemas' / f'{model.__name__}.json'
|
72
77
|
dump_schema(model, path)
|
73
|
-
return path
|
78
|
+
return abspath(path)
|
74
79
|
|
75
80
|
|
76
81
|
def model_json(model: BaseModel) -> str:
|