Index: geniuswebcore/test/geniusweb/inform/OptInTest.py
===================================================================
--- geniuswebcore/test/geniusweb/inform/OptInTest.py	(revision 94)
+++ geniuswebcore/test/geniusweb/inform/OptInTest.py	(revision 95)
@@ -1,7 +1,9 @@
 from datetime import datetime
 import json
+from typing import List
 import unittest
 
 from pyson.ObjectMapper import ObjectMapper
+from unitpy.GeneralTests import GeneralTests
 from uri.uri import URI 
 
@@ -13,6 +15,4 @@
 from geniusweb.issuevalue.Bid import Bid
 from geniusweb.issuevalue.DiscreteValue import DiscreteValue
-from unitpy.GeneralTests import GeneralTests
-from typing import List
 
 
@@ -20,14 +20,14 @@
     maxDiff = None
         
-    bid1 =  Bid({"iss":  DiscreteValue("val1")})
-    bid2 =  Bid({"iss":  DiscreteValue("val2")})
-    partyA =  PartyId("partyA")
-    partyB =  PartyId("partyB")
+    bid1 = Bid({"iss": DiscreteValue("val1")})
+    bid2 = Bid({"iss": DiscreteValue("val2")})
+    partyA = PartyId("partyA")
+    partyB = PartyId("partyB")
     voteA1 = Vote(partyA, bid1, 2, 9)
-    voteB1 =  Vote(partyB, bid1, 2, 9)
-    voteB2 =  Vote(partyB, bid2, 2, 9)
+    voteB1 = Vote(partyB, bid1, 2, 9)
+    voteB2 = Vote(partyB, bid2, 2, 9)
 
     votesA = Votes(partyA, set([voteA1]))
-    votesB = Votes(partyB,set([voteB1, voteB2]))
+    votesB = Votes(partyB, set([voteB1, voteB2]))
 
     optIn1 = OptIn([votesA, votesB])
@@ -36,11 +36,11 @@
     jackson = ObjectMapper();
 
-    asJson="{\"OptIn\":{\"votes\":[{\"Votes\":{\"actor\":\"partyA\",\"votes\":[{\"Vote\":{\"actor\":\"partyA\",\"bid\":{\"issuevalues\":{\"iss\":\"val1\"}},\"minPower\":2,\"maxPower\":9}}]}},{\"Votes\":{\"actor\":\"partyB\",\"votes\":[{\"Vote\":{\"actor\":\"partyB\",\"bid\":{\"issuevalues\":{\"iss\":\"val2\"}},\"minPower\":2,\"maxPower\":9}},{\"Vote\":{\"actor\":\"partyB\",\"bid\":{\"issuevalues\":{\"iss\":\"val1\"}},\"minPower\":2,\"maxPower\":9}}]}}]}}"
+    asJson = "{\"OptIn\":{\"votes\":[{\"Votes\":{\"actor\":\"partyA\",\"votes\":[{\"Vote\":{\"actor\":\"partyA\",\"bid\":{\"issuevalues\":{\"iss\":\"val1\"}},\"minPower\":2,\"maxPower\":9}}]}},{\"Votes\":{\"actor\":\"partyB\",\"votes\":[{\"Vote\":{\"actor\":\"partyB\",\"bid\":{\"issuevalues\":{\"iss\":\"val2\"}},\"minPower\":2,\"maxPower\":9}},{\"Vote\":{\"actor\":\"partyB\",\"bid\":{\"issuevalues\":{\"iss\":\"val1\"}},\"minPower\":2,\"maxPower\":9}}]}}]}}"
 
-    def getGeneralTestData(self) -> List[List[OptIn]] :
+    def getGeneralTestData(self) -> List[List[OptIn]]:
         return [[self.optIn1, self.optIn1a], [self.optIn2]]
         
     def getGeneralTestStrings(self) -> List[str]:
-        return ["OptIn.*Votes.*Vote.*partyA.*iss.*val1.*2.*Votes.*Vote.*partyB.*iss.*val2.*.*2.*Vote.*partyB.*iss.*val1.*2.*", 
+        return ["OptIn.*Votes.*Vote.*partyA.*iss.*val1.*2.*Votes.*Vote.*partyB.*iss.*val.*.*2.*Vote.*partyB.*iss.*val.*2.*",
                 "OptIn.*Votes.*Vote.*partyA.*iss.*val.*2.*"]
 
Index: geniuswebcore/test/geniusweb/progress/ProgressRoundsTest.py
===================================================================
--- geniuswebcore/test/geniusweb/progress/ProgressRoundsTest.py	(revision 94)
+++ geniuswebcore/test/geniusweb/progress/ProgressRoundsTest.py	(revision 95)
@@ -1,65 +1,107 @@
-
 from datetime import datetime
+import json
+from typing import List
 import unittest
+from unittest.mock import Mock
 
 from pyson.ObjectMapper import ObjectMapper
+from unitpy.GeneralTests import GeneralTests
 
+from geniusweb import progress
+from geniusweb.deadline.DeadlineRounds import DeadlineRounds
 from geniusweb.progress.Progress import Progress
 from geniusweb.progress.ProgressRounds import ProgressRounds
+from geniusweb.progress.ProgressTime import ProgressTime
 
 
-class ProgressRoundsTest(unittest.TestCase):
-    pyson=ObjectMapper()
-    progress = ProgressRounds(12, 0, datetime.fromtimestamp(100000.9))
-    progress1 = ProgressRounds(12, 0, datetime.fromtimestamp(100000.9))
-    progress2 = ProgressRounds(11, 0, datetime.fromtimestamp(100000.9))
-    progresjson = {"ProgressRounds":{"duration":12,"currentRound":0,"endtime":100000900}}
-    final=ProgressRounds(12,12, datetime.fromtimestamp(100000.9));
+class ProgressRoundsTest(unittest.TestCase, GeneralTests[Progress]): 
+    deadline = Mock(DeadlineRounds)
+    TESTROUNDS = 10
+    TESTTIME = 10  # milliseconds!
 
-    def testDeserialization(self):
-        self.assertEqual(self.progress, self.pyson.parse(self.progresjson, Progress))
+    date = datetime.fromtimestamp(98765 / 1000)
+    date0 = datetime.fromtimestamp(100000 / 1000)
 
-    def testSerialization(self):
-        print(self.pyson.toJson(self.progress))
-        self.assertEqual(self.progresjson, self.pyson.toJson(self.progress))
-    
-    def testRepr(self):
-        self.assertEqual("ProgressRounds[0 of 12,100000.9]", repr(self.progress))
-        
-    def testEqual(self):
-        self.assertEqual(self.progress, self.progress1)
-        self.assertNotEqual(self.progress, self.progress2)
+    deadline1 = ProgressRounds(20, 0, date)
+    deadline2 = ProgressRounds(20, 0, date)
+    deadline3 = ProgressRounds(30, 0, date)
+    deadline4 = ProgressTime(20, date0)
+    deadline5 = ProgressTime(20, date)
+    jackson = ObjectMapper()
+    progressstring = "{\"ProgressRounds\":{\"duration\":10,\"currentRound\":0,\"endtime\":98765}}"
 
-        self.assertEqual(hash(self.progress), hash(self.progress1))
-        self.assertNotEqual(hash(self.progress), hash(self.progress2))
-        
-    def testDuration(self):
-        self.assertEqual(12, self.progress.getDuration())
-        
+    start = 1234
+    end = datetime.fromtimestamp((start + TESTTIME) / 1000)
+    pr = ProgressRounds(TESTROUNDS, 4, end)
+
+    def setUp(self):
+        self.deadline.getRounds = Mock(return_value=self.TESTROUNDS)
+        self.progress = ProgressRounds(self.deadline.getRounds(), 0, self.date)
+
+    def getGeneralTestData(self) -> List[List[Progress]]:
+        return [[self.deadline1, self.deadline2], [self.deadline3], [self.deadline4], [self.deadline5]]
+
+    def getGeneralTestStrings(self) -> List[str]:
+        return ["ProgressRounds\\[0.*20\\]",
+                "ProgressRounds\\[0.*30\\]", "ProgressTime\\[100000.*20ms\\]",
+                "ProgressTime\\[98765.*20ms\\]"]
+
+    def testInit(self):
+        self.assertEqual(0, self.progress.get(1))
+
+    def testCurrentRound(self):
+        self.assertEqual(0, self.progress.getCurrentRound())
+
     def testAdvance(self):
-        prog=self.progress.advance()
-        self.assertEqual(1, prog.getCurrentRound())
-        
-    def testAdvanceFinal(self):
-        self.final.advance()
-        
-    def testTerminationTime(self):
-        self.assertEqual(datetime.fromtimestamp(100000.9), self.progress.getTerminationTime())
-        
-    def testIsPastDeadline(self):
-        self.assertFalse(self.progress.isPastDeadline(500))        
-        self.assertFalse(self.progress.isPastDeadline(100000900))
-        self.assertTrue(self.progress.isPastDeadline(100000901))
-        
-        self.assertTrue(self.final.isPastDeadline(100))
-        
-    def testGet(self):
-        self.assertEqual(0, self.progress.get(100000900-1))
-        # get ignores the time deadline. 
-        self.assertEqual(0, self.progress.get(100000901))
-        
-        #check final if all rounds completed.
-        self.assertEqual(1, self.final.get(100000900-1))
-        
-        halfway = ProgressRounds(12,6, datetime.fromtimestamp(100000900));
-        self.assertEqual(0.5, halfway.get(100000900-1) )
+        p = self.progress
+        n = 0;
+        while n <= self.TESTROUNDS:
+            self.assertEqual((float(n) / self.TESTROUNDS), p.get(1))
+            n = n + 1
+            p = p.advance()
+
+    def testAdvanceWhenDeadlineReached(self):
+        p = ProgressRounds(self.TESTROUNDS, 9, self.date)
+        p = p.advance()
+        self.assertEqual(1, p.get(1))
+
+    def testSerialize(self):
+        print(json.dumps(self.jackson.toJson(self.progress)))
+        self.assertEqual(json.loads(self.progressstring), self.jackson.toJson(self.progress))
+
+    def testDeserialize(self):
+        self.assertEqual(self.progress,
+                self.jackson.parse(json.loads(self.progressstring), Progress))
+
+    def testIllegalArg1(self):
+        self.assertRaises(ValueError, lambda:ProgressRounds(10, 11, self.date))
+
+    def testIllegalArg2(self):
+        self.assertRaises(ValueError, lambda:ProgressRounds(10, -1, self.date))
+
+    def pastDeadlinetest(self):
+        self.assertFalse(self.pr.isPastDeadline(self.start));
+        self.assertTrue(self.pr.isPastDeadline(self.start + self.TESTTIME + 1))
+        self.assertFalse(self.pr.isPastDeadline(self.start + self.TESTTIME - 1))
+        self.assertTrue(ProgressRounds(self.TESTROUNDS, self.TESTROUNDS, self.end)
+                .isPastDeadline(self.start + self.TESTTIME + 1))
+
+    def terminationTimetest(self):
+        self.assertEquals(self.start + self.TESTTIME, self.pr.getTerminationTime().getTime())
+
+    def gettest(self):
+        # time does not matter for rounds-based deadline
+        self.assertEqual(0.4, self.pr.get(self.start));
+        self.assertEqual(0.4, self.pr.get(self.start + self.TESTTIME + 1))
+        self.assertEqual(0.4, self.pr.get(self.start + self.TESTTIME))
+        self.assertEqual(0.4, self.pr.get(self.start + self.TESTTIME / 2))
+        self.assertEqual(0.4, self.pr.get(self.start - 10))
+        self.assertEqual(0.4, self.pr.get(self.start + self.TESTTIME + 10))
+
+        self.assertEqual(0.1,
+                ProgressRounds(self.TESTROUNDS, 1, self.end).get(self.start))
+        self.assertEqual(1,
+                ProgressRounds(self.TESTROUNDS, self.TESTROUNDS, self.end).get(self.start));
+
+    def totalRoundstest(self):
+        self.assertEqual(10, self.pr.getTotalRounds())
Index: geniuswebcore/test/geniusweb/progress/ProgressTimeTest.py
===================================================================
--- geniuswebcore/test/geniusweb/progress/ProgressTimeTest.py	(revision 94)
+++ geniuswebcore/test/geniusweb/progress/ProgressTimeTest.py	(revision 95)
@@ -1,48 +1,71 @@
-
 from datetime import datetime
+import json
+from typing import List
 import unittest
 
 from pyson.ObjectMapper import ObjectMapper
+from unitpy.GeneralTests import GeneralTests
 
 from geniusweb.progress.Progress import Progress
-from geniusweb.progress.ProgressRounds import ProgressRounds
 from geniusweb.progress.ProgressTime import ProgressTime
 
 
-class ProgressTimeTest(unittest.TestCase):
-    pyson=ObjectMapper()
-    progress = ProgressTime(1999, datetime.fromtimestamp(100000.9))
-    progress1 = ProgressTime(1999, datetime.fromtimestamp(100000.9))
-    progress2 = ProgressTime(999, datetime.fromtimestamp(100000.9))
-    progress3 = ProgressTime(1999, datetime.fromtimestamp(100001.9))
-    progresjson = {"ProgressTime":{"duration":1999, 'start':100000900}}
+class ProgressTimeTest (unittest.TestCase, GeneralTests[Progress]):
+	# we set T0 quite high because Python has trouble handling small datetime
+	T0 = 100000
+	TIMEZERO = datetime.fromtimestamp(T0 / 1000)
+	TESTTIME = 10  # milliseconds!
+	progress1 = ProgressTime(TESTTIME, TIMEZERO)
+	progress1a = ProgressTime(TESTTIME, TIMEZERO)
+	progress2 = ProgressTime(200, TIMEZERO)
 
-    def testDeserialization(self):
-        self.assertEqual(self.progress, self.pyson.parse(self.progresjson, Progress))
+	jackson = ObjectMapper()
+	progressstring = "{\"ProgressTime\":{\"duration\":10,\"start\":100000}}"
 
-    def testSerialization(self):
-        print(self.pyson.toJson(self.progress))
-        self.assertEqual(self.progresjson, self.pyson.toJson(self.progress))
-    
-    def testRepr(self):
-        self.assertEqual("ProgressTime[100000.9 , 1999ms]", repr(self.progress))
-        
-    def testEqual(self):
-        self.assertEqual(self.progress, self.progress1)
-        self.assertNotEqual(self.progress, self.progress2)
-        self.assertNotEqual(self.progress, self.progress3)
-        self.assertEqual(hash(self.progress), hash(self.progress1))
-        self.assertNotEqual(hash(self.progress), hash(self.progress2))
-        self.assertNotEqual(hash(self.progress), hash(self.progress3))
-        
-    def testPastDeadline(self):
-        self.assertFalse(self.progress.isPastDeadline(100000900+1999))        
-        self.assertTrue(self.progress.isPastDeadline(100000900+1999+1))
-        
-    def testTerminationTime(self):
-        self.assertEqual(datetime.fromtimestamp((100000900+1999)/1000), self.progress.getTerminationTime())
-        
-    def testGet(self):
-        self.assertEqual(0, self.progress.get(100000.9))
-        self.assertEqual(1, self.progress.get(100000.9+1999))
-        self.assertEqual(0.5, self.progress.get(100000.9+1999/2))
+	start = 1234
+	pr = ProgressTime(TESTTIME, datetime.fromtimestamp(start / 1000))
+
+	def getGeneralTestData(self) -> List[List[Progress]]:
+		return [[self.progress1, self.progress1a], [self.progress2]]
+	
+	def getGeneralTestStrings(self) -> List[str]:
+		return ["ProgressTime\\[100000.*10ms\\]",
+				"ProgressTime\\[100000.*200ms\\]"]
+
+	def testInit(self):
+		self.assertEqual(0, self.progress1.get(0))
+
+	def testAdvancingTime(self):
+		for n in range(0, self.TESTTIME):
+			self.assertEqual(float(n) / self.TESTTIME,
+					self.progress1.get(self.T0 + n))
+
+	def testAdvanceWhenDeadlineReached(self):
+		progress = ProgressTime(self.TESTTIME, self.TIMEZERO)
+		self.assertEqual(1, self.progress1.get(self.T0 + self.TESTTIME));
+
+	def testSerialize(self):
+		actual = self.jackson.toJson(self.progress1)
+		print(actual)
+		self.assertEqual(json.loads(self.progressstring), actual)
+
+	def testDeserialize(self):
+		newprog = self.jackson.parse(json.loads(self.progressstring), 	ProgressTime)
+		# we can't directly compare with progress since that's a hacked
+		# object...
+		self.assertEqual(self.TESTTIME, newprog.getDuration())
+		self.assertEqual(self.T0, 1000 * newprog.getStart().timestamp())
+
+	def pastDeadlinetest(self):
+		self.assertTrue(self.pr.isPastDeadline(self.start + self.TESTTIME + 1))
+		self.assertFalse(self.pr.isPastDeadline(self.start + self.TESTTIME - 1))
+
+	def terminationTimetest(self):
+		self.assertEqual(self.start + self.TESTTIME, self.pr.getTerminationTime().getTime())
+
+	def gettest(self):
+		self.assertEqual(0, self.pr.get(self.start))
+		self.assertEqual(1, self.pr.get(self.start + self.TESTTIME));
+		self.assertEqual(0.5, self.pr.get(self.start + self.TESTTIME / 2));
+		self.assertEqual(0, self.pr.get(self.start - 10))
+		self.assertEqual(1, self.pr.get(self.start + self.TESTTIME + 10))
Index: geniuswebcore/test/geniusweb/protocol/session/learn/LearnStateTest.py
===================================================================
--- geniuswebcore/test/geniusweb/protocol/session/learn/LearnStateTest.py	(revision 94)
+++ geniuswebcore/test/geniusweb/protocol/session/learn/LearnStateTest.py	(revision 95)
@@ -25,7 +25,7 @@
 	PARTY2 = "party2"
 	PARTY1 = "party1"
-	party1id =  PartyId(PARTY1)
-	party2id =  PartyId(PARTY2)
-	deadline =  DeadlineTime(10000)
+	party1id = PartyId(PARTY1)
+	party2id = PartyId(PARTY2)
+	deadline = DeadlineTime(10000)
 	partyprofile1 = Mock(PartyWithProfile)
 	partyprofile2 = Mock(PartyWithProfile)
@@ -39,8 +39,7 @@
 		self.params = self.params.With("negotiationdata",
 				["12b5f909-0079-43ac-a8ac-a31794391012"])
-
 		
-		self.progressnotdone.isPastDeadline=Mock(return_value=False)
-		self.progressdone.isPastDeadline=Mock(return_value=True)
+		self.progressnotdone.isPastDeadline = Mock(return_value=False)
+		self.progressdone.isPastDeadline = Mock(return_value=True)
 
 		# define team1
@@ -62,16 +61,15 @@
 		participants = [self.team1, self.team2]
 		settings = LearnSettings(participants, self.deadline)
-		self.state =LearnState([],[],None, settings)
+		self.state = LearnState([], [], None, settings)
 
 		self.connectedstate = self.state.WithParty(self.party1id, self.partyprofile1)\
 				.WithParty(self.party2id, self.partyprofile2).WithProgress(self.progressnotdone)
 
-
 	def testsmokeTestNull(self):
-		self.assertRaises(ValueError, lambda:LearnState([],[],None, None))
+		self.assertRaises(ValueError, lambda:LearnState([], [], None, None))
 
 	def testsmokeTest(self):
 		settings = Mock(LearnSettings)
-		LearnState([],[],None,settings)
+		LearnState([], [], None, settings)
 
 	def testgetAgreementsTest(self):
@@ -97,9 +95,9 @@
 		self.assertNotEqual(None, self.connectedstate.checkAction(self.party1id,
 				EndNegotiation(self.party1id)))
-		self.assertNotEqual(None,self.connectedstate.checkAction(self.party1id,
+		self.assertNotEqual(None, self.connectedstate.checkAction(self.party1id,
 				LearningDone(self.party2id)))
 
 		# check a good action is allowed
-		self.assertEqual(None,self.connectedstate.checkAction(self.party1id,
+		self.assertEqual(None, self.connectedstate.checkAction(self.party1id,
 				LearningDone(self.party1id)))
 
@@ -107,5 +105,5 @@
 		learned = self.connectedstate.WithAction(self.party1id,
 				LearningDone(self.party1id))
-		self.assertNotEqual(None, 
+		self.assertNotEqual(None,
 				learned.checkAction(self.party1id, LearningDone(self.party1id)))
 
@@ -121,4 +119,4 @@
 
 	def testgetResultTest(self):
-		res = self.connectedstate.getResult()
+		res = self.connectedstate.getResults()[0]
 		self.assertEqual(0, len(res.getAgreements().getMap()))
