Package: pji
pjiAn new easy-to-use python interaction for judgement written by Python.Some more features are supported, such as interaction test.InstallationYou can simply install it withpipcommand line from the official PyPI site.pip install pjiFor more information about installation, you can refer to theinstallation guide.DocumentationThe detailed documentation are hosted onhttps://hansbug.github.io/pji.Only english version is provided now, the chinese documentation is still under development.Quick Startpjiuses fork to create child processes, pipe for inter-process communication, and the linux permission system to ensure evaluation security.As a result,pjionly works on Linux systems, and you must have root permissions to use it.Use With Command-Linepjiis used based on configuration files, and the command line help information is as followspji-hOutput as followsUsage: pji [OPTIONS]

Options:
  -v, --version             Show package's version information.
  -s, --script FILE         Path of pji script.  [default: pscript.yml]
  -t, --task TEXT           Task going to be executed.  [default: main]
  -e, --environ TEXT        Environment variables (loaded before global
                            config).

  -E, --environ_after TEXT  Environment variables (loaded after global
                            config).

  -h, --help                Show this message and exit.A Simple ExampleHere's an simple example. In this case, the test data is generated automatically, and then the running test of the script to be tested is performed with restricted permissions, and the results are sent back and logs are logged.Here is the configuration filetest_dispatch.yml.global:
  environ:
    PATH: /root:${PATH}
    INPUT: 2 3
  use_sys_env:
    - PATH
    - LC_ALL
    - LANG
tasks:
  run_python:
    sections:
      - name: get_test_info
        inputs:
          - "copy:test_script.py:test_script.py"
        outputs:
          - "tag:wc_result.txt:wc"
          - "tag:input_result.txt:input"
        infos:
          wc: "tag:wc"
          input: "tag:input"
        info_dump: "test_info.txt"
        commands:
          - args: "cat test_script.py | wc -l"
            stdout: wc_result.txt
          - args: "echo ${INPUT}"
            stdout: input_result.txt
      - name: generate_base64
        outputs:
          - "tag:base64.txt:b64"
        infos:
          b64: "tag:b64"
        commands:
          - args: "echo ${INPUT} | base64"
            stdout: base64.txt
      - name: run_result
        identification: nobody
        inputs:
          - "copy:test_script.py:test_script.py:r--:nobody"
          - "tag:b64:base64.txt:r--:nobody"
        outputs:
          - "tag:result.txt:result"
          - "copy:result.txt:test_result.txt"
        infos:
          result: "tag:result"
        commands:
          - args: "cat base64.txt | python test_script.py"
            stdout: result.txt
          - 'true'Script file going to be testedtest_script.pyimportbase64if__name__=='__main__':_line=base64.b64decode(input()).decode()print(sum([int(item.strip())foritemin_line.split(' ')ifitem.strip()]))Place the abovementioned files to directory/root/123, and then run the followingpjicommand.pji-s/root/123/test_dispatch.yml-trun_pythonThe output should beSection 'get_test_info' start ...
Coping file from '/root/123/test_script.py' to '/tmp/tmp6rsk6t2o/test_script.py' ... COMPLETE
Running 'cat test_script.py | wc -l' ... SUCCESS, time: 0.002s / 0.002s, memory: 18.875 MiB
Running 'echo ${INPUT}' ... SUCCESS, time: 0.004s / 0.003s, memory: 19.125 MiB
Saving file from '/tmp/tmp6rsk6t2o/wc_result.txt' to tag 'wc' ... COMPLETE
Saving file from '/tmp/tmp6rsk6t2o/input_result.txt' to tag 'input' ... COMPLETE
Collecting result information ... COMPLETE
Dumping result information to '/root/123/test_info.txt' ... COMPLETE
Section 'get_test_info' execute completed!

Section 'generate_base64' start ...
Running 'echo ${INPUT} | base64' ... SUCCESS, time: 0.003s / 0.002s, memory: 19.15625 MiB
Saving file from '/tmp/tmp_n5ftp5d/base64.txt' to tag 'b64' ... COMPLETE
Collecting result information ... COMPLETE
Section 'generate_base64' execute completed!

Section 'run_result' start ...
Coping file from '/root/123/test_script.py' to '/tmp/tmphcbmt0j9/test_script.py' ... COMPLETE
Loading tag 'b64' to '/tmp/tmphcbmt0j9/base64.txt' ... COMPLETE
Running 'cat base64.txt | python test_script.py' ... SUCCESS, time: 0.025s / 0.030s, memory: 19.16796875 MiB
Running 'true' ... SUCCESS, time: 0.000s / 0.001s, memory: 19.18359375 MiB
Saving file from '/tmp/tmphcbmt0j9/result.txt' to tag 'result' ... COMPLETE
Coping file from '/tmp/tmphcbmt0j9/result.txt' to '/root/123/test_result.txt' ... COMPLETE
Collecting result information ... COMPLETE
Section 'run_result' execute completed!

Task success.The file passed back/root/123/result.txt5Furthermore, when this command line, which is slightly different from the one above, is executedpji-s/root/123/test_dispatch.yml-trun_python-E"INPUT=1 2 3 4 5 6 7"The content of/root/123/result.txtshould be28And, if you need the full running information, just use the following command with-ioptionpji-s/root/123/test_dispatch.yml-trun_python-E"INPUT=1 2 3 4 5 6 7"-itest_info.jsonAn extra log filetest_info.jsonwill be exported{"ok":true,"sections":[{"commands":[{"completed":true,"limit":{"max_cpu_time":null,"max_memory":null,"max_output_size":null,"max_process_number":null,"max_real_time":null,"max_stack":null},"ok":true,"result":{"cpu_time":0.000896,"exitcode":0,"max_memory":19709952.0,"real_time":0.002176523208618164,"signal":null},"status":"SUCCESS"},{"completed":true,"limit":{"max_cpu_time":null,"max_memory":null,"max_output_size":null,"max_process_number":null,"max_real_time":null,"max_stack":null},"ok":true,"result":{"cpu_time":0.002518,"exitcode":0,"max_memory":19881984.0,"real_time":0.0010895729064941406,"signal":null},"status":"SUCCESS"}],"information":{"input":"1 2 3 4 5 6 7\n","wc":"5\n"},"name":"get_test_info","ok":true},{"commands":[{"completed":true,"limit":{"max_cpu_time":null,"max_memory":null,"max_output_size":null,"max_process_number":null,"max_real_time":null,"max_stack":null},"ok":true,"result":{"cpu_time":0.002568,"exitcode":0,"max_memory":19922944.0,"real_time":0.0018069744110107422,"signal":null},"status":"SUCCESS"}],"information":{"b64":"MSAyIDMgNCA1IDYgNwo=\n"},"name":"generate_base64","ok":true},{"commands":[{"completed":true,"limit":{"max_cpu_time":null,"max_memory":null,"max_output_size":null,"max_process_number":null,"max_real_time":null,"max_stack":null},"ok":true,"result":{"cpu_time":0.023656999999999997,"exitcode":0,"max_memory":19947520.0,"real_time":0.027228593826293945,"signal":null},"status":"SUCCESS"},{"completed":true,"limit":{"max_cpu_time":null,"max_memory":null,"max_output_size":null,"max_process_number":null,"max_real_time":null,"max_stack":null},"ok":true,"result":{"cpu_time":0.001723,"exitcode":0,"max_memory":19955712.0,"real_time":0.0009958744049072266,"signal":null},"status":"SUCCESS"}],"information":{"result":"28\n"},"name":"run_result","ok":true}]}Use In Scriptpjican be used like the above method with native python.For example, we can build the following script to run the test mentioned aboveimportcodecsfrompji.entryimportload_pji_scriptif__name__=='__main__':_script=load_pji_script('/root/123/test_dispatch.yml')_success,_result=_script('run_python')print(_success)print(_result)withcodecs.open('/root/123/test_result.txt','r')asrf:print(rf.read())The output should beTrue
[('get_test_info', (True, [<RunResult status: SUCCESS>, <RunResult status: SUCCESS>], {'wc': '5\n', 'input': '2 3\n'})), ('generate_base64', (True, [<RunResult status: SUCCESS>], {'b64': 'MiAzCg==\n'})), ('run_result', (True, [<RunResult status: SUCCESS>, <RunResult status: SUCCESS>], {'result': '5\n'}))]
5Another case for extra environment variable attachedimportcodecsfrompji.entryimportload_pji_scriptif__name__=='__main__':_script=load_pji_script('/root/123/test_dispatch.yml')_success,_result=_script('run_python',environ_after={'INPUT':'1 2 3 4 5 6 7'})print(_success)print(_result)withcodecs.open('/root/123/test_result.txt','r')asrf:print(rf.read())The output should beTrue
[('get_test_info', (True, [<RunResult status: SUCCESS>, <RunResult status: SUCCESS>], {'wc': '5\n', 'input': '1 2 3 4 5 6 7\n'})), ('generate_base64', (True, [<RunResult status: SUCCESS>], {'b64': 'MSAyIDMgNCA1IDYgNwo=\n'})), ('run_result', (True, [<RunResult status: SUCCESS>, <RunResult status: SUCCESS>], {'result': '28\n'}))]
28Run Unittest / Building# create dev containermakerun_devIMAGE_DEV=python:3.6# after enter the docker container./install.sh# install requirements with chinese mirrorsourceenv.sh# add pji cli's environmentmakeunittest# run unittestmakebuild# build a standalone cli, placed at 'dist/pji'Licensepjireleased under the Apache 2.0 license.