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

mode to create standalone test output automatically [WIP] #209

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
52 changes: 52 additions & 0 deletions bin/deepstate/extract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function
import argparse


def main():
global candidateRuns, currentTest, s, passStart

parser = argparse.ArgumentParser(description="Extract standalone test information from a DeepState harness run")

parser.add_argument(
"run", type=str, help="Path to DeepState run output.")
parser.add_argument(
"template", type=str, help="Path to test template.")
parser.add_argument(
"output_file", type=str, help="Path to output standalone test.")

args = parser.parse_args()

run = []
with open(args.run, 'r') as rfile:
for line in rfile:
run.append(line)

newSource = []
with open(args.template, 'r') as tfile:
for line in tfile:
if "<<INSERT TEST CODE HERE>>" not in line:
newSource.append(line)
else:
for line in run:
if "/* START STANDALONE CODE */" in line:
newLine = line.split("/* START STANDALONE CODE */")[1]
newLine = newLine.split("/* END STANDALONE CODE */")[0]
newLine += "\n"
print(newLine[:-1])
newSource.append(newLine)

with open(args.output_file, 'w') as ntfile:
for line in newSource:
ntfile.write(line)

if "__main__" == __name__:
exit(main())
92 changes: 92 additions & 0 deletions bin/deepstate/standalone.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import print_function
import argparse


def main():
global candidateRuns, currentTest, s, passStart

parser = argparse.ArgumentParser(description="Add code to a DeepState harness to dump code for standalone test cases")

parser.add_argument(
"source", type=str, help="Path to input harness file.")
parser.add_argument(
"output_source", type=str, help="Path to output modified harness file.")
parser.add_argument(
"config", type=str, help="Path for configuration file listing functions to export to standalone.")

args = parser.parse_args()

functions = []

def annotate(call, f):
annotated = ""
pos = 0
spaces = ""
for c in call:
if c.isspace():
spaces += c
pos += 1
else:
break
arguments = call.split(f + "(")[1]
arguments = arguments.split(")")[0]
theArgs = arguments.split(",")
annotated += "LOG(TRACE) << "
annotated += '"/* START STANDALONE CODE */' + spaces + call[pos:call.find("(") + 1] + '" << '
if f != "assert":
for arg in theArgs[:-1]:
annotated += ("DeepState_Standalone_Wrap(" + arg + ') << ", " << ')
if len(theArgs) >= 1:
annotated += ("DeepState_Standalone_Wrap(" + theArgs[-1] + ') << ')
else:
for i in range(1, len(call)):
if call[-i] == ")":
endPos = i
break
annotated += '"' + call[call.find("(")+1:-endPos] + '" << '
annotated += '"); /* END STANDALONE CODE */";\n'
return annotated

with open(args.config, 'r') as cfile:
for line in cfile:
functions.append(line.split()[0])

for f in functions:
print("ADDING STANDALONE TEST GENERATION CODE FOR", f)

functions.append("assert")

oldSource = []
with open(args.source, 'r') as sfile:
for line in sfile:
oldSource.append(line);

newSource = []
inTests = False
for line in oldSource:
if inTests:
for f in functions:
if f+"(" in line:
print("ADDING TEST GENERATION CODE FOR:", line[:-1])
a = annotate(line, f)
print(a)
newSource.append(a)
elif "TEST(" in line:
inTests = True
newSource.append(line)

with open(args.output_source, 'w') as nsfile:
for line in newSource:
nsfile.write(line)

if "__main__" == __name__:
exit(main())
5 changes: 4 additions & 1 deletion bin/setup.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ setuptools.setup(
'deepstate-honggfuzz = deepstate.executors.fuzz.honggfuzz:main',

'deepstate-reduce = deepstate.executors.auxiliary.reducer:main',
'deepstate-ensembler = deepstate.executors.auxiliary.ensembler:main'
'deepstate-ensembler = deepstate.executors.auxiliary.ensembler:main',

'deepstate-add-standalone = deepstate.standalone:main',
'deepstate-extract-standalone = deepstate.extract:main',
]
})
19 changes: 19 additions & 0 deletions src/include/deepstate/DeepState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,25 @@ DEEPSTATE_INLINE static bool IsSymbolic(double x) {
return DeepState_IsSymbolicDouble(x);
}

DEEPSTATE_INLINE static int DeepState_Standalone_Wrap(int x) {
return x;
}

DEEPSTATE_INLINE static unsigned int DeepState_Standalone_Wrap(unsigned int x) {
return x;
}

DEEPSTATE_INLINE static std::string DeepState_Standalone_Wrap(char* x) {
if (x == NULL) {
return std::string("NULL");
} else {
std::string s = "\"";
s += std::string(x);
s += "\"";
return s;
}
}

// A test fixture.
class Test {
public:
Expand Down