示例#1
0
class RuntimeDataTestCases(unittest.TestCase):

  def setUp(self):
    self.dummy_rtd = RuntimeData()

  def tearDown(self):
    pass

  ########################
  ### User Layer Tests ###
  ########################
  def test_add_new_user(self):
    # case 1 - happy path
    uid = 1
    res = self.dummy_rtd.addNewUser(uid)
    self.assertTrue(res)

    # case 2 - user already exists
    res = self.dummy_rtd.addNewUser(uid)
    self.assertFalse(res)

    # case 3 - happy path
    uid = 2
    res = self.dummy_rtd.addNewUser(uid)
    self.assertTrue(res)

  def test_get_user(self):
    uid = 1

    # case 1 - user does not exists
    res = self.dummy_rtd.getUser(uid)
    self.assertIsNone(res)

    # case 2 - happy path
    expected = {'dummy':'data'}
    with patch.dict(self.dummy_rtd.data, {uid: expected}):
      res = self.dummy_rtd.getUser(uid)
      self.assertIsNotNone(res)
      self.assertDictEqual(expected, res)

  def test_update_user(self):
    uid = 10
    dummy_orig_jid = 1
    dummy_new_jid = 2
    mock_orig_data = {dummy_orig_jid:'data'}
    mock_new_data = {dummy_new_jid:dict(zip(self.dummy_rtd.valid_keys, self.dummy_rtd.default_values))}

    # case 1 - no user
    self.dummy_rtd.getUser = MagicMock(return_value=None)
    res = self.dummy_rtd.updateUser(uid, mock_new_data)
    self.assertFalse(res)

    self.dummy_rtd.getUser = MagicMock(return_value={})

    # case 2 - no data
    res = self.dummy_rtd.updateUser(uid, None)
    self.assertFalse(res)

    # case 3 - happy path
    self.dummy_rtd.data = {uid:mock_orig_data}
    res = self.dummy_rtd.updateUser(uid, mock_new_data)
    self.assertTrue(res)
    data = self.dummy_rtd.data[uid]
    expected = mock_orig_data.copy()
    expected.update(mock_new_data)
    self.assertDictEqual(expected, data)

  def test_del_user(self):
    uid = 1

    # case 1 - no user
    res = self.dummy_rtd.delUser(uid)
    self.assertIsNone(res)

    expected = {'dummy':'data'}
    self.dummy_rtd.data[uid] = expected

    # case 2 - happy path
    res = self.dummy_rtd.delUser(uid)
    self.assertIsNotNone(res)
    self.assertDictEqual(expected, res)
    self.assertRaises(KeyError, self.dummy_rtd.data.pop, uid)

  #######################
  ### Job Layer Tests ###
  #######################
  def test_gen_job_id(self):
    # case 1 - arg is not str
    test_data = 123456789
    expected = ''
    res = self.dummy_rtd._gen_job_id(test_data)
    self.assertEqual(expected, res)

    # case 2 - all legible characters
    for x in range(ord(' '), ord('~')+1):
      test_data = chr(x)
      res = self.dummy_rtd._gen_job_id(test_data)
      self.assertEqual(str(x), res)

  def test_create_job(self):
    uid = 1
    vid = '2'

    # case 1 - bad v_id
    self.dummy_rtd._gen_job_id = MagicMock(return_value='')
    self.assertRaises(RuntimeDataException, self.dummy_rtd.createJob, uid, vid) # TODO: check for correct expection?
    self.dummy_rtd._gen_job_id.assert_called_once_with(vid)

    # case 2 - job already exists
    jid = 50
    self.dummy_rtd._gen_job_id = MagicMock(return_value=jid)
    self.dummy_rtd.getJob = MagicMock(return_value={'some':'data'})
    self.assertRaises(RuntimeDataException, self.dummy_rtd.createJob, uid, vid) # TODO: check for correct expection?
    self.dummy_rtd._gen_job_id.assert_called_once_with(vid)
    self.dummy_rtd.getJob.assert_called_once_with(uid, jid)

    self.dummy_rtd._gen_job_id.reset_mock()
    self.dummy_rtd.getJob.reset_mock()

    # case 3 - failed to add job
    self.dummy_rtd._gen_job_id = MagicMock(return_value=jid)
    self.dummy_rtd.getJob = MagicMock(return_value=None)
    self.dummy_rtd.addNewJob = MagicMock(return_value=False)
    self.assertRaises(RuntimeDataException, self.dummy_rtd.createJob, uid, vid) # TODO: check for correct expection?
    self.dummy_rtd._gen_job_id.assert_called_once_with(vid)
    self.dummy_rtd.getJob.assert_called_once_with(uid, jid)
    self.dummy_rtd.addNewJob.assert_called_once_with(uid, jid, unittest.mock.ANY)

    self.dummy_rtd._gen_job_id.reset_mock()
    self.dummy_rtd.getJob.reset_mock()
    self.dummy_rtd.addNewJob.reset_mock()

    # case 4 - happy path
    self.dummy_rtd._gen_job_id = MagicMock(return_value=jid)
    self.dummy_rtd.getJob = MagicMock(return_value=None)
    self.dummy_rtd.addNewJob = MagicMock(return_value=True)
    start_time = datetime.utcnow()
    res_1, res_2 = self.dummy_rtd.createJob(uid, vid)
    end_time = datetime.utcnow()
    self.assertEqual(jid, res_1)
    time = datetime.utcfromtimestamp(res_2)
    assert(start_time < time < end_time)
    self.dummy_rtd._gen_job_id.assert_called_once_with(vid)
    self.dummy_rtd.getJob.assert_called_once_with(uid, jid)
    self.dummy_rtd.addNewJob.assert_called_once_with(uid, jid, unittest.mock.ANY)

  def test_is_job_dict(self):
    mock_dict = {}

    # case 1 - not a dict
    res = self.dummy_rtd._is_job_dict(None)
    self.assertFalse(res)

    # case 2 - dict doesn't have correct keys
    res = self.dummy_rtd._is_job_dict(mock_dict)
    self.assertFalse(res)

    # case 3 - happy path
    mock_dict = dict(zip(self.dummy_rtd.valid_keys, self.dummy_rtd.default_values))
    res = self.dummy_rtd._is_job_dict(mock_dict)
    self.assertTrue(res)

    # case 4 - dict has more than the required keys
    mock_dict.update({'bad_key':''})
    res = self.dummy_rtd._is_job_dict(mock_dict)
    self.assertFalse(res)

  def test_add_new_job(self):
    uid = 1
    jid = 50
    mock_data = dict(zip(self.dummy_rtd.valid_keys, self.dummy_rtd.default_values))

    # case 1 - data isn't a job dict
    self.dummy_rtd._is_job_dict = MagicMock(return_value=False)
    res = self.dummy_rtd.addNewJob(uid, jid, mock_data)
    self.assertFalse(res)
    self.dummy_rtd._is_job_dict.assert_called_once_with(mock_data)

    self.dummy_rtd._is_job_dict.reset_mock()

    # case 2 - user and job exists
    self.dummy_rtd._is_job_dict = MagicMock(return_value=True)
    self.dummy_rtd.getUser = MagicMock(return_value={})
    self.dummy_rtd.getJob = MagicMock(return_value={})
    res = self.dummy_rtd.addNewJob(uid, jid, mock_data)
    self.assertFalse(res)
    self.dummy_rtd._is_job_dict.assert_called_once_with(mock_data)
    self.dummy_rtd.getUser.assert_called_once_with(uid)
    self.dummy_rtd.getJob.assert_called_once_with(uid, jid)

    self.dummy_rtd._is_job_dict.reset_mock()
    self.dummy_rtd.getUser.reset_mock()
    self.dummy_rtd.getJob.reset_mock()

    # case 3 - user does not exist
    self.dummy_rtd._is_job_dict = MagicMock(return_value=True)
    self.dummy_rtd.getUser = MagicMock(return_value=None)
    self.dummy_rtd.addNewUser = MagicMock()
    self.dummy_rtd.updateUser = MagicMock(return_value=True)
    res = self.dummy_rtd.addNewJob(uid, jid, mock_data)
    self.assertTrue(res)
    self.dummy_rtd._is_job_dict.assert_called_once_with(mock_data)
    self.dummy_rtd.getUser.assert_called_once_with(uid)
    self.dummy_rtd.addNewUser.assert_called_once_with(uid)
    self.dummy_rtd.updateUser.assert_called_once_with(uid, {jid:mock_data})

    self.dummy_rtd._is_job_dict.reset_mock()
    self.dummy_rtd.getUser.reset_mock()
    self.dummy_rtd.addNewUser.reset_mock()

    # case 4 - user does exist, but job does not
    self.dummy_rtd._is_job_dict = MagicMock(return_value=True)
    self.dummy_rtd.getUser = MagicMock(return_value={})
    self.dummy_rtd.getJob = MagicMock(return_value=None)
    self.dummy_rtd.updateUser = MagicMock(return_value=True)
    res = self.dummy_rtd.addNewJob(uid, jid, mock_data)
    self.assertTrue(res)
    self.dummy_rtd._is_job_dict.assert_called_once_with(mock_data)
    self.dummy_rtd.getUser.assert_called_once_with(uid)
    self.dummy_rtd.getJob.assert_called_once_with(uid, jid)
    self.dummy_rtd.updateUser.assert_called_once_with(uid, {jid:mock_data})

  def test_get_job(self):
    uid = 1
    jid = 5
    mock_user_data = {}
    mock_job_data = dict(zip(self.dummy_rtd.valid_keys, self.dummy_rtd.default_values))

    # case 1 - User does not exist
    self.dummy_rtd.getUser = MagicMock(return_value=None)
    res = self.dummy_rtd.getJob(uid, jid)
    self.assertIsNone(res)
    self.dummy_rtd.getUser.assert_called_once_with(uid)

    self.dummy_rtd.getUser.reset_mock()

    # case 2 - User exists, job does not.
    self.dummy_rtd.getUser = MagicMock(return_value=mock_user_data)
    res = self.dummy_rtd.getJob(uid, jid)
    self.assertIsNone(res)
    self.dummy_rtd.getUser.assert_called_once_with(uid)

    self.dummy_rtd.getUser.reset_mock()

    # case 3 - User and job exist
    mock_user_data = {jid:mock_job_data}
    self.dummy_rtd.getUser = MagicMock(return_value=mock_user_data)
    res = self.dummy_rtd.getJob(uid, jid)
    self.assertIsNotNone(res)
    self.assertDictEqual(mock_job_data, res)
    self.dummy_rtd.getUser.assert_called_once_with(uid)

  def test_update_job(self):
    uid = 1
    jid = 5
    mock_job_data = dict(zip(self.dummy_rtd.valid_keys, self.dummy_rtd.default_values))

    # case 1 - data is not a job dict
    self.dummy_rtd._is_job_dict = MagicMock(return_value=False)
    res = self.dummy_rtd.updateJob(uid, jid, mock_job_data)
    self.assertFalse(res)
    self.dummy_rtd._is_job_dict.assert_called_once_with(mock_job_data)

    self.dummy_rtd._is_job_dict.reset_mock()

    # case 2 - data is a job dict, but job doesn't exist
    self.dummy_rtd._is_job_dict = MagicMock(return_value=True)
    self.dummy_rtd.getJob = MagicMock(return_value=None)
    res = self.dummy_rtd.updateJob(uid, jid, mock_job_data)
    self.assertFalse(res)
    self.dummy_rtd._is_job_dict.assert_called_once_with(mock_job_data)
    self.dummy_rtd.getJob.assert_called_once_with(uid, jid)

    self.dummy_rtd._is_job_dict.reset_mock()
    self.dummy_rtd.getJob.reset_mock()

    # case 3 - data is a job dict and job exists
    # ...prime the data structure so we can check it at the end.
    self.dummy_rtd.data = {uid:{jid:{}}}
    self.dummy_rtd._is_job_dict = MagicMock(return_value=True)
    self.dummy_rtd.getJob = MagicMock(return_value={})
    res = self.dummy_rtd.updateJob(uid, jid, mock_job_data)
    self.assertTrue(res)
    self.dummy_rtd._is_job_dict.assert_called_once_with(mock_job_data)
    self.dummy_rtd.getJob.assert_called_once_with(uid, jid)
    self.assertDictEqual(mock_job_data, self.dummy_rtd.data[uid][jid])

  def test_del_job(self):
    uid = 1
    jid = 5
    mock_job_data = dict(zip(self.dummy_rtd.valid_keys, self.dummy_rtd.default_values))

    # case 1 - User does not exist
    self.dummy_rtd.getUser = MagicMock(return_value=None)
    res = self.dummy_rtd.delJob(uid, jid)
    self.assertIsNone(res)
    self.dummy_rtd.getUser.assert_called_once_with(uid)

    self.dummy_rtd.getUser.reset_mock()

    # case 2 - User exists, job does not
    # ...prime the data structure so we can check it at the end.
    self.dummy_rtd.data = {uid:{}}
    self.dummy_rtd.getUser = MagicMock(return_value={})
    res = self.dummy_rtd.delJob(uid, jid)
    self.assertIsNone(res)
    self.dummy_rtd.getUser.assert_called_once_with(uid)

    self.dummy_rtd.getUser.reset_mock()

    # case 3 - User and job exist
    # ...prime the data structure so we can check it at the end.
    self.dummy_rtd.data = {uid:{jid:mock_job_data}}
    self.dummy_rtd.getUser = MagicMock(return_value={})
    res = self.dummy_rtd.delJob(uid, jid)
    self.assertIsNotNone(res)
    self.assertDictEqual(mock_job_data, res)
    self.dummy_rtd.getUser.assert_called_once_with(uid)
    # check that the job was removed from the data structure
    self.assertDictEqual({uid:{}}, self.dummy_rtd.data)

  ########################
  ### Data Layer Tests ###
  ########################
  def test_get_attribute(self):
    uid = 1
    jid = 5
    mock_job_data = dict(zip(self.dummy_rtd.valid_keys, self.dummy_rtd.default_values))

    # case 1 - job does not exist
    self.dummy_rtd.getJob = MagicMock(return_value=None)
    res = self.dummy_rtd.get_attribute(uid, jid, 'some_key')
    self.assertIsNone(res)
    self.dummy_rtd.getJob.assert_called_once_with(uid, jid)

    self.dummy_rtd.getJob.reset_mock()

    # case 2 - job exists, but key does not
    self.dummy_rtd.getJob = MagicMock(return_value=mock_job_data)
    res = self.dummy_rtd.get_attribute(uid, jid, 'some_key')
    self.assertIsNone(res)
    self.dummy_rtd.getJob.assert_called_once_with(uid, jid)

    self.dummy_rtd.getJob.reset_mock()

    # case 3 - job and key exist
    self.dummy_rtd.getJob = MagicMock(return_value=mock_job_data)
    res = self.dummy_rtd.get_attribute(uid, jid, 'stage')
    self.assertEqual('init', res)
    self.dummy_rtd.getJob.assert_called_once_with(uid, jid)

  def test_set_attribute(self):
    uid = 1
    jid = 5
    key='stage'
    value='done'
    mock_job_data = dict(zip(self.dummy_rtd.valid_keys, self.dummy_rtd.default_values))

    # case 1 - attribute does not exist
    self.dummy_rtd.get_attribute = MagicMock(return_value=None)
    res = self.dummy_rtd.set_attribute(uid, jid, key, value)
    self.assertFalse(res)
    self.dummy_rtd.get_attribute.assert_called_once_with(uid, jid, key)

    self.dummy_rtd.get_attribute.reset_mock()

    # case 2 - attribute exists, bad value
    self.dummy_rtd.get_attribute = MagicMock(return_value='init')
    res = self.dummy_rtd.set_attribute(uid, jid, key, None)
    self.assertFalse(res)
    self.dummy_rtd.get_attribute.assert_called_once_with(uid, jid, key)

    self.dummy_rtd.get_attribute.reset_mock()

    # case 3 - attribute exists, good value
    # ...prime the data structure so we can check it at the end.
    self.dummy_rtd.data = {uid:{jid:mock_job_data}}
    self.dummy_rtd.get_attribute = MagicMock(return_value='init')
    res = self.dummy_rtd.set_attribute(uid, jid, key, value)
    self.assertTrue(res)
    expected = mock_job_data
    expected[key] = value
    self.assertDictEqual(expected, self.dummy_rtd.data[uid][jid])
    self.dummy_rtd.get_attribute.assert_called_once_with(uid, jid, key)

  #######################
  ### Real World Test ###
  #######################
  def test_z_real_world_run(self):
    uid_1 = 1
    uid_2 = 2
    # two users can process the same video
    vid_1 = '99999999999'
    vid_2 = '99999999999'

    # Precondition
    self.assertDictEqual({}, self.dummy_rtd.data)

    # Real world run
    start_time = datetime.utcnow()
    jid_1, ts_1 = self.dummy_rtd.createJob(uid_1, vid_1)
    end_time = datetime.utcnow()

    # Check for correctness after adding user and job.
    self.assertEqual('5757575757575757575757', jid_1)
    time_1 = datetime.utcfromtimestamp(ts_1)
    assert(start_time < time_1 < end_time)
    expected_job_data_1 = dict(zip(self.dummy_rtd.valid_keys, self.dummy_rtd.default_values))
    expected_job_data_1['id'] = jid_1
    expected_job_data_1['v_id'] = vid_1
    expected_job_data_1['timestamp'] = ts_1
    expected_user_data_1 = {jid_1: expected_job_data_1}
    expected_data = {uid_1: expected_user_data_1}
    self.assertDictEqual(expected_data, self.dummy_rtd.data)

    # Check get and set functions
    res = self.dummy_rtd.getUser(uid_1)
    self.assertDictEqual(expected_user_data_1, res)

    res = self.dummy_rtd.getJob(uid_1, jid_1)
    self.assertDictEqual(expected_job_data_1, res)

    # update job data
    expected_job_data_1['stage'] = 'done'
    res = self.dummy_rtd.updateJob(uid_1, jid_1, expected_job_data_1)
    self.assertTrue(res)

    # verify update to job
    res = self.dummy_rtd.getJob(uid_1, jid_1)
    self.assertDictEqual(expected_job_data_1, res)

    # verify update to user
    expected_user_data_1.update({jid_1:expected_job_data_1})
    res = self.dummy_rtd.getUser(uid_1)
    self.assertDictEqual(expected_user_data_1, res)

    # Add second user and job
    start_time = datetime.utcnow()
    jid_2, ts_2 = self.dummy_rtd.createJob(uid_2, vid_2)
    end_time = datetime.utcnow()

    # Check for correctness after adding user and job.
    self.assertEqual('5757575757575757575757', jid_2)
    time_2 = datetime.utcfromtimestamp(ts_2)
    assert(start_time < time_2 < end_time)
    expected_job_data_2 = dict(zip(self.dummy_rtd.valid_keys, self.dummy_rtd.default_values))
    expected_job_data_2['id'] = jid_2
    expected_job_data_2['v_id'] = vid_2
    expected_job_data_2['timestamp'] = ts_2
    expected_user_data_2 = {jid_2: expected_job_data_2}
    expected_data.update({uid_2: expected_user_data_2})
    self.assertDictEqual(expected_data, self.dummy_rtd.data)

    # Check get and set functions
    res = self.dummy_rtd.getUser(uid_1)
    self.assertDictEqual(expected_user_data_1, res)
    res = self.dummy_rtd.getUser(uid_2)
    self.assertDictEqual(expected_user_data_2, res)

    res = self.dummy_rtd.getJob(uid_1, jid_1)
    self.assertDictEqual(expected_job_data_1, res)
    res = self.dummy_rtd.getJob(uid_2, jid_2)
    self.assertDictEqual(expected_job_data_2, res)

    # delete user 1
    expected_del = expected_data.pop(uid_1)
    res = self.dummy_rtd.delUser(uid_1)
    self.assertDictEqual(expected_del, res)

    # verify user deletion
    self.assertDictEqual(expected_data, self.dummy_rtd.data)
    res = self.dummy_rtd.getUser(uid_1)
    self.assertIsNone(res)

    # try and fail to add already running job to user 2
    self.assertRaises(RuntimeDataException, self.dummy_rtd.createJob, uid_2, vid_2)

    # successfully add second job for user 2
    vid_3 = '00000000000'
    start_time = datetime.utcnow()
    jid_3, ts_3 = self.dummy_rtd.createJob(uid_2, vid_3)
    end_time = datetime.utcnow()

    # Check for correctness after adding user and job.
    self.assertEqual('4848484848484848484848', jid_3)
    time_3 = datetime.utcfromtimestamp(ts_3)
    assert(start_time < time_3 < end_time)
    expected_job_data_3 = dict(zip(self.dummy_rtd.valid_keys, self.dummy_rtd.default_values))
    expected_job_data_3['id'] = jid_3
    expected_job_data_3['v_id'] = vid_3
    expected_job_data_3['timestamp'] = ts_3
    expected_user_data_2.update({jid_3: expected_job_data_3})
    expected_data.update({uid_2: expected_user_data_2})
    self.assertDictEqual(expected_data, self.dummy_rtd.data)

    # delete job 1 for user 2
    expected_del = expected_user_data_2.pop(jid_2)
    res = self.dummy_rtd.delJob(uid_2, jid_2)
    self.assertDictEqual(expected_del, res)

    # verify job deletion
    res = self.dummy_rtd.getUser(uid_2)
    self.assertDictEqual(expected_user_data_2, res)
    res = self.dummy_rtd.getJob(uid_2, jid_2)
    self.assertIsNone(res)

    # test get/set attribute
    new_value = 'new_value'
    res = self.dummy_rtd.set_attribute(uid_2, jid_3, 'stage', new_value)
    self.assertTrue(res)

    res = self.dummy_rtd.get_attribute(uid_2, jid_3, 'stage')
    self.assertEqual(new_value, res)

  def test_z_threaded_real_world_run(self):
    uid = 1
    jid = 5
    key='stage'
    new_value='done'
    mock_job_data = dict(zip(self.dummy_rtd.valid_keys, self.dummy_rtd.default_values))

    # Setup and verify precondition
    self.dummy_rtd.data = {uid:{jid:mock_job_data}}
    res = self.dummy_rtd.getJob(uid, jid)
    self.assertDictEqual(mock_job_data, res)

    t = Thread(target=self.dummy_rtd.set_attribute, args=(uid, jid, key, new_value))

    self.dummy_rtd.data_lock.acquire()
    t.start()
    time.sleep(1)
    self.assertTrue(t.is_alive())
    self.dummy_rtd.data_lock.release()
    t.join()
    self.assertFalse(t.is_alive())

    # Verify change
    mock_job_data[key]=new_value
    self.assertDictEqual(mock_job_data, self.dummy_rtd.data[uid][jid])
示例#2
0
 def setUp(self):
   self.dummy_rtd = RuntimeData()