Skip to content

Commit

Permalink
Compilation improvements (#38)
Browse files Browse the repository at this point in the history
* Print gcc output with colors

* Add option to compile with weaker flags

* Fix tests

* Remove hasattr check

* Bump version

* Small refactor

* Add test for --weak-compilation-flags

* Fix fixtures

* tmp fix, will be fixed in pr with checker/inwer
  • Loading branch information
MasloMaslane authored Jul 3, 2023
1 parent 31aef36 commit dfcdfd6
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/sinol_make/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from sinol_make import util

__version__ = "1.1.1"
__version__ = "1.1.2"

def configure_parsers():
parser = argparse.ArgumentParser(
Expand Down
6 changes: 5 additions & 1 deletion src/sinol_make/commands/run/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ def configure_subparser(self, subparser):
help='Python interpreter to use (default: python3)')
parser.add_argument('--java_compiler_path', type=str, default=compiler.get_java_compiler_path(),
help='Java compiler to use (default: javac)')
parser.add_argument('--weak_compilation_flags', dest='weak_compilation_flags', action='store_true',
help='use weaker compilation flags')
parser.add_argument('--apply_suggestions', dest='apply_suggestions', action='store_true',
help='apply suggestions from expected scores report')

Expand Down Expand Up @@ -191,8 +193,10 @@ def compile(self, solution):
self.COMPILATION_DIR, "%s.compile_log" % self.extract_file_name(solution))
source_file = os.path.join(os.getcwd(), "prog", self.get_solution_from_exe(solution))
output = os.path.join(self.EXECUTABLES_DIR, self.get_executable(solution))

try:
compile.compile(source_file, output, self.compilers, open(compile_log_file, "w"))
compile.compile(source_file, output, self.compilers,
open(compile_log_file, "w"), self.args.weak_compilation_flags)
print(util.info("Compilation of file %s was successful."
% self.extract_file_name(solution)))
return True
Expand Down
10 changes: 7 additions & 3 deletions src/sinol_make/helpers/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@
from sinol_make.interfaces.Errors import CompilationError
import os, subprocess, sys

def compile(program, output, compilers = None, compile_log = None):
def compile(program, output, compilers = None, compile_log = None, weak_compilation_flags = False):
"""
Compile a program
compilers - A dictionary of compilers to use. If not set, the default compilers will be used
"""
gcc_compilation_flags = '-Werror -Wall -Wextra -Wshadow -Wconversion -Wno-unused-result -Wfloat-equal'
if weak_compilation_flags:
gcc_compilation_flags = '-w' # Disable all warnings

ext = os.path.splitext(program)[1]
arguments = []
if ext == '.cpp':
arguments = [compilers['cpp_compiler_path'] or compiler.get_cpp_compiler_path(), program, '-o', output] + \
'--std=c++17 -O3 -lm -Werror -Wall -Wextra -Wshadow -Wconversion -Wno-unused-result -Wfloat-equal'.split(' ')
f'--std=c++17 -O3 -lm {gcc_compilation_flags} -fdiagnostics-color'.split(' ')
elif ext == '.c':
arguments = [compilers['c_compiler_path'] or compiler.get_c_compiler_path(), program, '-o', output] + \
'--std=c17 -O3 -lm -Werror -Wall -Wextra -Wshadow -Wconversion -Wno-unused-result -Wfloat-equal'.split(' ')
f'--std=c17 -O3 -lm {gcc_compilation_flags} -fdiagnostics-color'.split(' ')
elif ext == '.py':
if sys.platform == 'win32' or sys.platform == 'cygwin':
# TODO: Make this work on Windows
Expand Down
26 changes: 23 additions & 3 deletions tests/commands/run/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from sinol_make import configure_parsers


@pytest.mark.parametrize("create_package", [get_simple_package_path(), get_verify_status_package_path()], indirect=True)
@pytest.mark.parametrize("create_package", [get_simple_package_path()], indirect=True)
def test_simple(create_package, time_tool):
"""
Test a simple run.
Expand All @@ -21,7 +21,7 @@ def test_simple(create_package, time_tool):
command.run(args)


@pytest.mark.parametrize("create_package", [get_simple_package_path(), get_verify_status_package_path()], indirect=True)
@pytest.mark.parametrize("create_package", [get_simple_package_path()], indirect=True)
def test_no_expected_scores(capsys, create_package, time_tool):
"""
Test with no sinol_expected_scores in config.yml.
Expand Down Expand Up @@ -51,7 +51,7 @@ def test_no_expected_scores(capsys, create_package, time_tool):
assert "abc.cpp" in out


@pytest.mark.parametrize("create_package", [get_simple_package_path(), get_verify_status_package_path()], indirect=True)
@pytest.mark.parametrize("create_package", [get_simple_package_path()], indirect=True)
def test_apply_suggestions(create_package, time_tool):
"""
Test with no sinol_expected_scores in config.yml.
Expand Down Expand Up @@ -143,3 +143,23 @@ def test_flag_solutions(capsys, create_package, time_tool):
assert "abc1.cpp" in out
assert "abc2.cpp" in out
assert "abc3.cpp" not in out


@pytest.mark.parametrize("create_package", [get_weak_compilation_flags_package_path()], indirect=True)
def test_weak_compilation_flags(create_package):
"""
Test flag --weak-compilation-flags.
"""
parser = configure_parsers()
args = parser.parse_args(["run", "--time_tool", "time"])
command = Command()

with pytest.raises(SystemExit) as e:
command.run(args)

assert e.type == SystemExit
assert e.value.code == 1

args = parser.parse_args(["run", "--weak_compilation_flags", "--time_tool", "time"])
command = Command()
command.run(args)
4 changes: 2 additions & 2 deletions tests/commands/run/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def test_get_tests(create_package):
def test_execution(create_package, time_tool):
package_path = create_package
command = get_command(package_path)
command.args = argparse.Namespace(time_tool = time_tool)
command.args = argparse.Namespace(time_tool=time_tool, weak_compilation_flags=False)
solution = "abc.cpp"
executable = command.get_executable(solution)
result = command.compile_solutions([solution])
Expand Down Expand Up @@ -105,7 +105,7 @@ def test_calculate_points():
def test_run_solutions(create_package, time_tool):
package_path = create_package
command = get_command(package_path)
command.args = argparse.Namespace(solutions_report=False, time_tool=time_tool)
command.args = argparse.Namespace(solutions_report=False, time_tool=time_tool, weak_compilation_flags=False)
create_ins_outs(package_path, command)
command.tests = command.get_tests(None)
command.groups = list(sorted(set([command.get_group(test) for test in command.tests])))
Expand Down
8 changes: 8 additions & 0 deletions tests/commands/run/util.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import multiprocessing as mp
import os, glob

import argparse
import yaml
from ...util import *
from sinol_make.commands.run import Command
Expand All @@ -23,6 +24,7 @@ def get_command(path = None):
'java_compiler_path': compiler.get_java_compiler_path()
}
command.config = yaml.load(open(os.path.join(path, "config.yml"), "r"), Loader=yaml.FullLoader)
set_default_args(command)
return command

def create_ins(package_path, command):
Expand All @@ -47,3 +49,9 @@ def create_outs(package_path, command):
def create_ins_outs(package_path, command):
create_ins(package_path, command)
create_outs(package_path, command)


def set_default_args(command):
command.args = argparse.Namespace(
weak_compilation_flags=False
)
14 changes: 11 additions & 3 deletions tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@


@pytest.fixture
def create_package(path=None):
if path is None:
def create_package(request):
"""
Fixture to create a temporary directory with specified package (by default simple package).
Changes the current working directory to the package directory.
"""
if hasattr(request, 'param') and request.param is not None:
path = request.param
else:
path = get_simple_package_path()
task_id = os.path.basename(path)

tmpdir = tempfile.TemporaryDirectory()
package_path = os.path.join(tmpdir.name, "abc")
package_path = os.path.join(tmpdir.name, task_id)
shutil.copytree(path, package_path)
os.chdir(package_path)

Expand Down
6 changes: 6 additions & 0 deletions tests/packages/wcf/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
title: Package for testing --weak-compilation-flags
memory_limit: 16000
time_limit: 1000

scores:
1: 100
Empty file added tests/packages/wcf/in/.gitkeep
Empty file.
11 changes: 11 additions & 0 deletions tests/packages/wcf/prog/wcf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <bits/stdc++.h>

using namespace std;

int main() {
int a, b;
int c; // Unused variable

cin >> a >> b;
cout << a + b << endl;
}
7 changes: 7 additions & 0 deletions tests/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@ def get_verify_status_package_path():
Get path to package for veryfing status order (/test/packages/vso)
"""
return os.path.join(os.path.dirname(__file__), "packages", "vso")


def get_weak_compilation_flags_package_path():
"""
Get path to package for testing weak compilation flags (/test/packages/wcf)
"""
return os.path.join(os.path.dirname(__file__), "packages", "wcf")

0 comments on commit dfcdfd6

Please sign in to comment.