Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.2.18 #3

Merged
merged 2 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,5 @@ tmp.py
test_dir/
.DS_Store

mapping.json

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "sflkit"
version = "0.2.17"
version = "0.2.18"
authors = [
{ name = "Marius Smytzek", email = "marius.smytzek@cispa.de" },
]
Expand Down
2 changes: 1 addition & 1 deletion src/sflkit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


def instrument_config(conf: Config):
instrumentation = DirInstrumentation(conf.visitor)
instrumentation = DirInstrumentation(conf.visitor, conf.mapping.path)
instrumentation.instrument(
conf.target_path,
conf.instrument_working,
Expand Down
15 changes: 14 additions & 1 deletion src/sflkit/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def __init__(self, path: Union[str, configparser.ConfigParser] = None):
self.instrument_working = None
self.runner = None
self.mapping = None
self.mapping_path = None
if path:
if isinstance(path, configparser.ConfigParser):
config = path
Expand Down Expand Up @@ -143,10 +144,12 @@ def __init__(self, path: Union[str, configparser.ConfigParser] = None):
self.metrics = [Spectrum.Ochiai]

run_id_generator = IDGenerator()
if "mapping" in events:
self.mapping_path = Path(events["mapping"])
try:
self.mapping = EventMapping.load(self)
except InstrumentationError:
self.mapping = EventMapping()
self.mapping = EventMapping(path=self.mapping_path)
if "passing" in events:
self.passing = self.get_event_files(
list(csv.reader([events["passing"]]))[0],
Expand Down Expand Up @@ -198,6 +201,7 @@ def create_from_values(
visitor: ASTVisitor = None,
passing: List[EventFile] = None,
failing: List[EventFile] = None,
mapping: EventMapping = None,
instrument_include: List[str] = None,
instrument_exclude: List[str] = None,
instrument_working: str = None,
Expand All @@ -220,6 +224,10 @@ def create_from_values(
conf.instrument_exclude = instrument_exclude if instrument_exclude else list()
conf.instrument_working = instrument_working
conf.runner = runner
if mapping:
conf.mapping = mapping
if mapping.path:
conf.mapping_path = mapping.path
return conf

@staticmethod
Expand Down Expand Up @@ -263,6 +271,7 @@ def create(
metrics=None,
passing=None,
failing=None,
mapping_path=None,
working=None,
include=None,
exclude=None,
Expand All @@ -288,6 +297,8 @@ def create(
conf["events"]["passing"] = passing
if failing:
conf["events"]["failing"] = failing
if mapping_path:
conf["events"]["mapping"] = mapping_path
if working:
conf["instrumentation"]["path"] = working
if include:
Expand Down Expand Up @@ -320,6 +331,8 @@ def write(self, path):
conf["events"]["passing"] = ",".join(e.path for e in self.passing)
if self.failing:
conf["events"]["failing"] = ",".join(e.path for e in self.failing)
if self.mapping_path:
conf["events"]["mapping"] = str(self.mapping_path)
if self.instrument_working:
conf["instrumentation"]["path"] = str(self.instrument_working)
if self.instrument_include:
Expand Down
10 changes: 4 additions & 6 deletions src/sflkit/instrumentation/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import json
from abc import abstractmethod
from typing import List

from sflkitlib.events import event
from pathlib import Path
from typing import List, Optional

from sflkit import Config
from sflkit.language.visitor import ASTVisitor
from sflkit.mapping import EventMapping


class Instrumentation:
def __init__(self, visitor: ASTVisitor):
def __init__(self, visitor: ASTVisitor, mapping_path: Optional[Path] = None):
self.visitor = visitor
self.events = EventMapping()
self.events = EventMapping(path=mapping_path)

@abstractmethod
def instrument(
Expand Down
7 changes: 4 additions & 3 deletions src/sflkit/instrumentation/dir_instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import queue
import re
import shutil
from pathlib import Path
from typing import List, Optional, Iterable, Tuple

from sflkit.instrumentation import Instrumentation
Expand All @@ -11,9 +12,9 @@


class DirInstrumentation(Instrumentation):
def __init__(self, visitor: ASTVisitor):
super().__init__(visitor)
self.file_instrumentation = FileInstrumentation(visitor)
def __init__(self, visitor: ASTVisitor, mapping_path: Optional[Path] = None):
super().__init__(visitor, mapping_path)
self.file_instrumentation = FileInstrumentation(visitor, mapping_path)

@staticmethod
def check_included(element: str, includes: Optional[Iterable[str]]):
Expand Down
9 changes: 5 additions & 4 deletions src/sflkit/instrumentation/file_instrumentation.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
from typing import List
from pathlib import Path
from typing import List, Optional

from sflkit.instrumentation import Instrumentation
from sflkit.language.visitor import ASTVisitor
from sflkit.mapping import EventMapping


class FileInstrumentation(Instrumentation):
def __init__(self, visitor: ASTVisitor):
super().__init__(visitor)
def __init__(self, visitor: ASTVisitor, mapping_path: Optional[Path] = None):
super().__init__(visitor, mapping_path)

def instrument(
self, src: str, dst: str, suffixes: List[str] = None, file: str = ""
):
self.visitor.instrument(src, dst, file)
self.events = EventMapping(
{event.event_id: event for event in self.visitor.events}
{event.event_id: event for event in self.visitor.events}, self.events.path
)
26 changes: 17 additions & 9 deletions src/sflkit/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,45 @@ class InstrumentationError(RuntimeError):


class EventMapping:
def __init__(self, mapping: Dict[int, Event] = None):
def __init__(
self, mapping: Dict[int, Event] = None, path: Optional[os.PathLike] = None
):
self.mapping = mapping or dict()
self.path = path

def get(self, event_id) -> Optional[Event]:
return self.mapping.get(event_id, None)

@staticmethod
def get_path(identifier: str):
def get_path(identifier: str) -> Path:
return SFLKIT_PATH / f"{identifier}.json"

@staticmethod
def load(config: Any):
if not hasattr(config, "identifier"):
raise InstrumentationError(f"Argument does not have an identifier")
return EventMapping.load_from_file(config.identifier())
return EventMapping.load_from_file(
config.mapping_path or EventMapping.get_path(config.identifier()),
config.target_path,
)

@staticmethod
def load_from_file(identifier: str):
file = EventMapping.get_path(identifier)
def load_from_file(file: Path, path: os.PathLike):
if file.exists():
return EventMapping(load_json(file))
return EventMapping(load_json(file), file)
else:
raise InstrumentationError(
f"Cannot find information about instrumentation of {identifier or file}"
f"Cannot find information about instrumentation of {path or file}"
)

def write(self, config):
if not hasattr(config, "identifier"):
raise InstrumentationError(f"Argument does not have an identifier")
SFLKIT_PATH.mkdir(parents=True, exist_ok=True)
file = self.get_path(config.identifier())
if self.path:
file = self.path
else:
SFLKIT_PATH.mkdir(parents=True, exist_ok=True)
file = self.get_path(config.identifier())
with file.open("w") as fp:
json.dump(list(self.mapping.values()), fp, cls=EventEncoder)

Expand Down
1 change: 1 addition & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def test_create_config(self):
config.visitor,
config.passing,
config.failing,
config.mapping,
config.instrument_include,
config.instrument_exclude,
config.instrument_working,
Expand Down
15 changes: 15 additions & 0 deletions tests/test_instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,21 @@ def test_complex_structure_include(self):
)
)

def test_mapping_output(self):
instrument_config(
Config.create(
path=os.path.join(BaseTest.TEST_RESOURCES, "test_instrumentation"),
language="python",
events="line",
predicates="line",
working=BaseTest.TEST_DIR,
mapping_path="mapping.json",
)
)
mapping = Path("mapping.json")
self.assertTrue(mapping.exists())
self.assertTrue(mapping.is_file())


class TestLib(BaseTest):
@classmethod
Expand Down
Loading