Skip to content

Commit

Permalink
roll in unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ahouseholder committed Sep 25, 2023
1 parent 57cc285 commit 6834c98
Show file tree
Hide file tree
Showing 11 changed files with 1,130 additions and 1 deletion.
64 changes: 64 additions & 0 deletions test/cvd_states/test_cvss_patterns.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright (c) 2023. Carnegie Mellon University
#
# See LICENSE for details

import unittest
from enum import Enum

import vultron.cvd_states.patterns.cvss31 as cvss
from vultron.cvd_states.hypercube import CVDmodel


class MyTestCase(unittest.TestCase):
def setUp(self):
self.model = CVDmodel()

def tearDown(self):
pass

def test_cvss_31_e(self):
for state in self.model.states:
result = cvss.cvss_31_e(state)
# result should always be a list of non-zero length of strings of non-zero length
self.assertIsInstance(result, list)
for item in result:
self.assertIsInstance(item, Enum)

def test_cvss_31_rl(self):
for state in self.model.states:
result = cvss.cvss_31_rl(state)
# result should always be a list of non-zero length of strings of non-zero length
self.assertIsInstance(result, list)
for item in result:
self.assertIsInstance(item, Enum)

def test_cvss_31(self):
for state in self.model.states:
result = cvss.cvss_31(state)
# result should always be a list of non-zero length of strings of non-zero length
self.assertIsInstance(result, list)
for item in result:
self.assertIsInstance(item, Enum)

def test_cvss_exploitation_state(self):
for state in self.model.states:
result = cvss.cvss_31_e(state)
# if A in state, then Exploitation: Active should be in result
if "A" in state:
self.assertIn(cvss.CVSS_31_E.HIGH, result)
self.assertIn(cvss.CVSS_31_E.FUNCTIONAL, result)
elif "X" in state:
self.assertIn(cvss.CVSS_31_E.HIGH, result)
self.assertIn(cvss.CVSS_31_E.FUNCTIONAL, result)
self.assertIn(cvss.CVSS_31_E.PROOF_OF_CONCEPT, result)
else:
self.assertIn(cvss.CVSS_31_E.UNPROVEN, result)
self.assertIn(cvss.CVSS_31_E.NOT_DEFINED, result)

self.assertNotIn(cvss.CVSS_31_E.PROOF_OF_CONCEPT, result)
self.assertNotIn(cvss.CVSS_31_E.FUNCTIONAL, result)
self.assertNotIn(cvss.CVSS_31_E.HIGH, result)


if __name__ == "__main__":
unittest.main()
48 changes: 48 additions & 0 deletions test/cvd_states/test_embargo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright (c) 2023. Carnegie Mellon University
#
# See LICENSE for details

import unittest

import vultron.cvd_states.hypercube as sg
import vultron.cvd_states.patterns.embargo as mb
from vultron.cvd_states.errors import StateValidationError


class MyTestCase(unittest.TestCase):
def setUp(self):
self.model = sg.CVDmodel()

def tearDown(self):
pass

def test_reject_bogus_states(self):
funcs = [mb.can_start_embargo, mb.embargo_viable]
bogus_states = ["abbso", "abs", "absd", "absdx", "absdxa", "absdpxa"]
for func in funcs:
for state in bogus_states:
self.assertRaises(StateValidationError, func, state)

def test_embargo_viable(self):
m = self.model

# walk all the states and check the embargo_viable function
for state in m.states:
if "pxa" in state:
self.assertTrue(mb.embargo_viable(state))
else:
self.assertFalse(mb.embargo_viable(state))

def test_can_start_embargo(self):
m = self.model

# walk all the states and check the can_start_embargo function
for state in m.states:
if "dpxa" in state:
self.assertTrue(mb.can_start_embargo(state))
else:
self.assertFalse(mb.can_start_embargo(state))


if __name__ == "__main__":
unittest.main()
91 changes: 90 additions & 1 deletion test/cvd_states/test_hypercube.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,100 @@

import vultron.cvd_states.hypercube as hc
import vultron.cvd_states.states
from vultron.cvd_states.errors import TransitionValidationError
from vultron.cvd_states.states import CS_pxa
from vultron.cvd_states.validations import is_valid_transition


class MyTestCase(unittest.TestCase):
pass
def test_proto_states(self):
ps = hc._proto_states()
self.assertEqual(len(ps), 6)
for x in "vfdpxa":
s = f"{x.lower()}{x.upper()}"
self.assertIn(s, ps)

def test_create_states(self):
states = hc._create_states()
self.assertEqual(len(states), 32)
count = 0
for p, x, a in product("pP", "xX", "aA"):
s = "".join([p, x, a])
for allowed in ["vfd", "Vfd", "VFd", "VFD"]:
a = f"{allowed}{s}"
self.assertIn(a, states)
count += 1
for disallowed in ["vFd", "vfD", "vFD", "VfD"]:
d = f"{disallowed}{s}"
self.assertNotIn(d, states)
self.assertEqual(count, len(states))

def test_create_graph(self):
G = hc._create_graph()
states = hc._create_states()
self.assertEqual(len(G.nodes), len(states))
for state in hc._create_states():
self.assertIn(state, G.nodes)

def test_diffstate(self):
states = hc._create_states()
for s1, s2 in product(states, states):
try:
is_valid_transition(s1, s2)
except TransitionValidationError:
continue

# only one character should be different
self.assertNotEqual(s1, s2)
diff = [x for x in zip(s1, s2) if x[0] != x[1]]
self.assertEqual(len(diff), 1)

# and it should be a lower to upper case transition
self.assertTrue(diff[0][0].islower())
self.assertTrue(diff[0][1].isupper())
self.assertEqual(diff[0][0].upper(), diff[0][1])

def test_model_states(self):
states = hc._create_states()
m = hc.CVDmodel()
self.assertEqual(len(m.states), len(states))
for state in states:
self.assertIn(state, m.states)

def test_model_graph(self):
m = hc.CVDmodel()
self.assertEqual(len(m.G.nodes), len(m.states))
for state in m.states:
self.assertIn(state, m.G.nodes)

def test_model_previous_state(self):
m = hc.CVDmodel()
for state in m.states:
previous = m.previous_state(state)
for pred in m.G.predecessors(state):
self.assertIn(pred, previous)

def test_model_next_state(self):
m = hc.CVDmodel()
for state in m.states:
next = m.next_state(state)
for succ in m.G.successors(state):
self.assertIn(succ, next)

def test_paths_between(self):
m = hc.CVDmodel()
paths = list(m.paths_between("vfdpxa", "VFDPXA"))
self.assertEqual(len(paths), 70)

def test_paths_from(self):
m = hc.CVDmodel()
paths = list(m.paths_from("vfdpxa"))
self.assertEqual(len(paths), 70)

def test_paths_to(self):
m = hc.CVDmodel()
paths = list(m.paths_to("VFDPXA"))
self.assertEqual(len(paths), 70)


if __name__ == "__main__":
Expand Down
30 changes: 30 additions & 0 deletions test/cvd_states/test_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) 2023. Carnegie Mellon University
#
# See LICENSE for details

import unittest
from enum import Enum

import vultron.cvd_states.patterns.info as info
from vultron.cvd_states.hypercube import CVDmodel


class MyTestCase(unittest.TestCase):
def setUp(self):
self.model = CVDmodel()

def tearDown(self):
pass

def test_info(self):
for state in self.model.states:
result = info.info(state)
# result should always be a list of non-zero length of strings of non-zero length
self.assertIsInstance(result, list)
self.assertGreater(len(result), 0)
for item in result:
self.assertIsInstance(item, Enum)


if __name__ == "__main__":
unittest.main()
57 changes: 57 additions & 0 deletions test/cvd_states/test_pattern_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright (c) 2023. Carnegie Mellon University
#
# See LICENSE for details

import unittest
from enum import IntEnum

from vultron.cvd_states.enums.utils import (
enum_item_in_list,
enum_list_to_string_list,
uniq_enum_iter,
unique_enum_list,
)


class Foo(IntEnum):
No = 0
Yes = 1


class Bar(IntEnum):
No = 0
Yes = 1


class MyTestCase(unittest.TestCase):
def setUp(self):
pass

def tearDown(self):
pass

def test_enum_list_to_string_list(self):
list_of_items = [Foo.No, Bar.Yes]
results = enum_list_to_string_list(list_of_items)
self.assertEqual(results, ["Foo.No", "Bar.Yes"])

def test_enum_item_in_list(self):
list_of_items = [Foo.No, Bar.Yes]
for test_item in [Foo.No, Bar.Yes]:
self.assertTrue(enum_item_in_list(test_item, list_of_items))
for test_item in [Foo.Yes, Bar.No]:
self.assertFalse(enum_item_in_list(test_item, list_of_items))

def test_uniq_enum_iter(self):
list_of_items = [Foo.No, Bar.Yes, Foo.No, Bar.Yes]
results = list(uniq_enum_iter(list_of_items))
self.assertEqual(results, [Foo.No, Bar.Yes])

def test_unique_enum_list(self):
list_of_items = [Foo.No, Bar.Yes, Foo.No, Bar.Yes]
results = unique_enum_list(list_of_items)
self.assertEqual(results, [Foo.No, Bar.Yes])


if __name__ == "__main__":
unittest.main()
34 changes: 34 additions & 0 deletions test/cvd_states/test_potential_actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (c) 2023. Carnegie Mellon University
#
# See LICENSE for details

import unittest

from vultron.cvd_states.hypercube import CVDmodel
from vultron.cvd_states.patterns import potential_actions as pa


class MyTestCase(unittest.TestCase):
def setUp(self):
self.model = CVDmodel()
pass

def tearDown(self):
pass

def test_pa_action(self):
for state in self.model.states:
result = pa.action(state)
# actions should be a list
self.assertIsInstance(result, list)
# actions should be non-empty
self.assertGreater(len(result), 0)
# actions should be a list of enums
for a in result:
self.assertIsInstance(a, pa.Actions)
# actions should be unique
self.assertEqual(len(result), len(set(result)))


if __name__ == "__main__":
unittest.main()
Loading

0 comments on commit 6834c98

Please sign in to comment.