Example #1
0
 def test_full_path(self):
     serialize = SerializeModel()
     a = ModelFile("a", True)
     b = ModelFile("b", True)
     b.add_child(ModelFile("ba", False))
     b.add_child(ModelFile("bb", True))
     c = ModelFile("c", True)
     ca = ModelFile("ca", True)
     ca.add_child(ModelFile("caa", False))
     ca.add_child(ModelFile("cab", False))
     c.add_child(ca)
     cb = ModelFile("cb", False)
     c.add_child(cb)
     c.eta = 100
     files = [a, b, c]
     out = parse_stream(serialize.model(files))
     data = json.loads(out["data"])
     self.assertEqual(3, len(data))
     self.assertEqual("a", data[0]["full_path"])
     self.assertEqual("b", data[1]["full_path"])
     self.assertEqual("b/ba", data[1]["children"][0]["full_path"])
     self.assertEqual("b/bb", data[1]["children"][1]["full_path"])
     self.assertEqual("c", data[2]["full_path"])
     self.assertEqual("c/ca", data[2]["children"][0]["full_path"])
     self.assertEqual("c/ca/caa", data[2]["children"][0]["children"][0]["full_path"])
     self.assertEqual("c/ca/cab", data[2]["children"][0]["children"][1]["full_path"])
     self.assertEqual("c/cb", data[2]["children"][1]["full_path"])
Example #2
0
 def test_fail_add_child_to_nondir(self):
     file_parent = ModelFile("parent", False)
     file_child1 = ModelFile("child1", True)
     with self.assertRaises(TypeError) as context:
         file_parent.add_child(file_child1)
     self.assertTrue(
         str(context.exception).startswith(
             "Cannot add child to a non-directory"))
Example #3
0
 def test_parent(self):
     a = ModelFile("a", True)
     aa = ModelFile("aa", True)
     a.add_child(aa)
     aaa = ModelFile("aaa", False)
     aa.add_child(aaa)
     self.assertIsNone(a.parent)
     self.assertEqual(a, aa.parent)
     self.assertEqual(aa, aaa.parent)
Example #4
0
 def test_child(self):
     file_parent = ModelFile("parent", True)
     file_child1 = ModelFile("child1", True)
     file_child2 = ModelFile("child2", False)
     self.assertEqual(0, len(file_parent.get_children()))
     file_parent.add_child(file_child1)
     self.assertEqual([file_child1], file_parent.get_children())
     file_parent.add_child(file_child2)
     self.assertEqual([file_child1, file_child2],
                      file_parent.get_children())
Example #5
0
 def test_updated_children(self):
     model_before = Model()
     model_after = Model()
     a1 = ModelFile("a", True)
     aa1 = ModelFile("aa", False)
     aa1.local_size = 100
     a1.add_child(aa1)
     a2 = ModelFile("a", True)
     aa2 = ModelFile("aa", False)
     aa2.local_size = 200
     a2.add_child(aa2)
     model_before.add_file(a1)
     model_after.add_file(a2)
     diff = ModelDiffUtil.diff_models(model_before, model_after)
     self.assertEqual([ModelDiff(ModelDiff.Change.UPDATED, a1, a2)], diff)
Example #6
0
    def test_extract_dir_raises_error_on_no_local_files(self):
        self.mock_is_archive.return_value = True

        a = ModelFile("a", True)
        a.remote_size = 100
        aa = ModelFile("aa", False)
        aa.remote_size = 50
        a.add_child(aa)
        ab = ModelFile("ab", False)
        ab.remote_size = 50
        a.add_child(ab)

        with self.assertRaises(ExtractDispatchError) as ctx:
            self.dispatch.extract(a)
        self.assertTrue(
            str(ctx.exception).startswith(
                "Directory does not contain any archives"))
Example #7
0
    def test_extract_dir_exits_command_early_on_shutdown(self):
        # Send extract dir command with two archives
        # Call shutdown after first extract but before second
        # Verify second extract is not called
        self.mock_is_archive.return_value = True

        self.call_stop = False

        def _extract_archive(**kwargs):
            print(kwargs)
            self.call_stop = True
            time.sleep(0.5)  # wait a bit so shutdown is called

        self.mock_extract_archive.side_effect = _extract_archive

        a = ModelFile("a", True)
        a.local_size = 200
        aa = ModelFile("aa", False)
        aa.local_size = 100
        a.add_child(aa)
        ab = ModelFile("ab", False)
        ab.local_size = 100
        a.add_child(ab)

        self.dispatch.add_listener(self.listener)
        self.dispatch.extract(a)

        while not self.call_stop:
            pass
        self.dispatch.stop()

        while self.mock_extract_archive.call_count < 1 \
                or self.listener.extract_failed.call_count < 1:
            pass
        self.listener.extract_completed.assert_not_called()
        self.listener.extract_failed.assert_called_once_with("a", True)
        self.assertEqual(1, self.mock_extract_archive.call_count)
Example #8
0
 def test_full_path(self):
     file_a = ModelFile("a", True)
     file_aa = ModelFile("aa", True)
     file_a.add_child(file_aa)
     file_aaa = ModelFile("aaa", True)
     file_aa.add_child(file_aaa)
     file_ab = ModelFile("ab", True)
     file_a.add_child(file_ab)
     self.assertEqual("a", file_a.full_path)
     self.assertEqual("a/aa", file_aa.full_path)
     self.assertEqual("a/aa/aaa", file_aaa.full_path)
     self.assertEqual("a/ab", file_ab.full_path)
Example #9
0
 def test_fail_add_child_twice(self):
     file_parent = ModelFile("parent", True)
     file_parent.add_child(ModelFile("child1", True))
     file_parent.add_child(ModelFile("child2", True))
     with self.assertRaises(ValueError) as context:
         file_parent.add_child(ModelFile("child1", True))
     self.assertTrue(
         str(context.exception).startswith(
             "Cannot add child more than once"))
     with self.assertRaises(ValueError) as context:
         file_parent.add_child(ModelFile("child2", True))
     self.assertTrue(
         str(context.exception).startswith(
             "Cannot add child more than once"))
Example #10
0
    def test_status(self):
        self.mock_is_archive.return_value = True
        self.send_count = 0
        self.rx_count = 0

        # noinspection PyUnusedLocal
        def _extract(**kwargs):
            # barrier implementation
            while self.send_count <= self.rx_count:
                pass
            self.rx_count += 1

        self.mock_extract_archive.side_effect = _extract

        a = ModelFile("a", True)
        a.local_size = 200
        aa = ModelFile("aa", False)
        aa.local_size = 100
        a.add_child(aa)
        ab = ModelFile("ab", False)
        ab.local_size = 100
        a.add_child(ab)
        b = ModelFile("b", True)
        b.local_size = 100
        ba = ModelFile("ba", False)
        ba.local_size = 100
        b.add_child(ba)
        c = ModelFile("c", False)
        c.local_size = 100

        # Initial status should be empty
        status = self.dispatch.status()
        self.assertEqual(0, len(status))

        self.dispatch.add_listener(self.listener)
        self.dispatch.extract(a)
        self.dispatch.extract(b)
        self.dispatch.extract(c)

        status = self.dispatch.status()
        self.assertEqual(3, len(status))
        self.assertEqual("a", status[0].name)
        self.assertEqual(True, status[0].is_dir)
        self.assertEqual(ExtractStatus.State.EXTRACTING, status[0].state)
        self.assertEqual("b", status[1].name)
        self.assertEqual(True, status[1].is_dir)
        self.assertEqual(ExtractStatus.State.EXTRACTING, status[1].state)
        self.assertEqual("c", status[2].name)
        self.assertEqual(False, status[2].is_dir)
        self.assertEqual(ExtractStatus.State.EXTRACTING, status[2].state)

        # Wait for first dir to start extracting
        self.send_count = 1
        while self.rx_count < self.send_count:
            pass

        status = self.dispatch.status()
        self.assertEqual(3, len(status))
        self.assertEqual("a", status[0].name)
        self.assertEqual(True, status[0].is_dir)
        self.assertEqual(ExtractStatus.State.EXTRACTING, status[0].state)
        self.assertEqual("b", status[1].name)
        self.assertEqual(True, status[1].is_dir)
        self.assertEqual(ExtractStatus.State.EXTRACTING, status[1].state)
        self.assertEqual("c", status[2].name)
        self.assertEqual(False, status[2].is_dir)
        self.assertEqual(ExtractStatus.State.EXTRACTING, status[2].state)

        # After first directory finishes
        self.send_count = 2
        while self.listener.extract_completed.call_count < 1:
            pass
        self.listener.extract_completed.assert_called_with("a", True)

        status = self.dispatch.status()
        self.assertEqual(2, len(status))
        self.assertEqual("b", status[0].name)
        self.assertEqual(True, status[0].is_dir)
        self.assertEqual(ExtractStatus.State.EXTRACTING, status[0].state)
        self.assertEqual("c", status[1].name)
        self.assertEqual(False, status[1].is_dir)
        self.assertEqual(ExtractStatus.State.EXTRACTING, status[1].state)

        # After second directory finishes
        self.send_count = 3
        while self.listener.extract_completed.call_count < 2:
            pass
        self.listener.extract_completed.assert_called_with("b", True)

        status = self.dispatch.status()
        self.assertEqual(1, len(status))
        self.assertEqual("c", status[0].name)
        self.assertEqual(False, status[0].is_dir)
        self.assertEqual(ExtractStatus.State.EXTRACTING, status[0].state)

        # After third/last file finishes
        self.send_count = 4
        while self.listener.extract_completed.call_count < 3:
            pass
        self.listener.extract_completed.assert_called_with("c", False)

        status = self.dispatch.status()
        self.assertEqual(0, len(status))
Example #11
0
    def test_extract_dir_does_not_extract_split_rar_files(self):
        self.mock_is_archive.return_value = True
        self.actual_calls = set()

        def _extract(archive_path: str, out_dir_path: str):
            self.actual_calls.add((archive_path, out_dir_path))

        self.mock_extract_archive.side_effect = _extract

        a = ModelFile("a", True)
        a.local_size = 80
        aa = ModelFile("aa.rar", False)
        aa.local_size = 10
        a.add_child(aa)
        aa0 = ModelFile("aa.r00", False)
        aa0.local_size = 10
        a.add_child(aa0)
        aa1 = ModelFile("aa.r01", False)
        aa1.local_size = 10
        a.add_child(aa1)
        aa2 = ModelFile("aa.r02", False)
        aa2.local_size = 10
        a.add_child(aa2)
        aa15 = ModelFile("aa.r15", False)
        aa15.local_size = 10
        a.add_child(aa15)
        ab = ModelFile("ab.rar", False)
        ab.local_size = 10
        a.add_child(ab)
        ab0 = ModelFile("ab.r000", False)
        ab0.local_size = 10
        a.add_child(ab0)
        ab1 = ModelFile("ab.r001", False)
        ab1.local_size = 10
        a.add_child(ab1)
        ac = ModelFile("ac", True)
        ac.local_size = 20
        a.add_child(ac)
        aca = ModelFile("aca", True)
        aca.local_size = 20
        ac.add_child(aca)
        acaa = ModelFile("acaa.rar", False)
        acaa.local_size = 10
        aca.add_child(acaa)
        acaa0 = ModelFile("acaa.r00", False)
        acaa0.local_size = 10
        aca.add_child(acaa0)

        self.dispatch.add_listener(self.listener)
        self.dispatch.extract(a)
        while self.listener.extract_completed.call_count < 1:
            pass
        self.listener.extract_completed.assert_called_once_with("a", True)

        golden_calls = {
            (os.path.join(self.local_path, "a",
                          "aa.rar"), os.path.join(self.out_dir_path, "a")),
            (os.path.join(self.local_path, "a",
                          "ab.rar"), os.path.join(self.out_dir_path, "a")),
            (os.path.join(self.local_path, "a", "ac", "aca", "acaa.rar"),
             os.path.join(self.out_dir_path, "a", "ac", "aca")),
        }
        self.assertEqual(3, self.mock_extract_archive.call_count)
        self.assertEqual(golden_calls, self.actual_calls)
Example #12
0
    def test_extract_dir_skips_non_archive_files(self):
        # noinspection SpellCheckingInspection
        def _is_archive(archive_path: str):
            return archive_path in (os.path.join(self.local_path, "a", "aa",
                                                 "aaa"),
                                    os.path.join(self.local_path, "a", "aa",
                                                 "aac", "aaca"),
                                    os.path.join(self.local_path, "a", "ab",
                                                 "aba"))

        self.mock_is_archive.side_effect = _is_archive
        self.actual_calls = set()

        def _extract(archive_path: str, out_dir_path: str):
            self.actual_calls.add((archive_path, out_dir_path))

        self.mock_extract_archive.side_effect = _extract

        a = ModelFile("a", True)
        a.local_size = 500
        aa = ModelFile("aa", True)
        aa.local_size = 300
        a.add_child(aa)
        aaa = ModelFile("aaa", False)
        aaa.local_size = 100
        aa.add_child(aaa)
        aab = ModelFile("aab", False)
        aab.local_size = 100
        aa.add_child(aab)
        aac = ModelFile("aac", True)
        aac.local_size = 100
        aa.add_child(aac)
        aaca = ModelFile("aaca", False)
        aaca.local_size = 100
        aac.add_child(aaca)
        ab = ModelFile("ab", True)
        ab.local_size = 100
        a.add_child(ab)
        aba = ModelFile("aba", False)
        aba.local_size = 100
        ab.add_child(aba)
        ac = ModelFile("ac", False)
        ac.local_size = 100
        a.add_child(ac)

        self.dispatch.add_listener(self.listener)
        self.dispatch.extract(a)
        while self.listener.extract_completed.call_count < 1:
            pass
        self.listener.extract_completed.assert_called_once_with("a", True)

        golden_calls = {
            (os.path.join(self.local_path, "a", "aa",
                          "aaa"), os.path.join(self.out_dir_path, "a", "aa")),
            (os.path.join(self.local_path, "a", "aa", "aac", "aaca"),
             os.path.join(self.out_dir_path, "a", "aa", "aac")),
            (os.path.join(self.local_path, "a", "ab",
                          "aba"), os.path.join(self.out_dir_path, "a", "ab")),
        }
        self.assertEqual(3, self.mock_extract_archive.call_count)
        self.assertEqual(golden_calls, self.actual_calls)
Example #13
0
    def test_child_equality(self):
        l_a = ModelFile("a", True)
        l_a.remote_size = 3 + 1 + 2
        l_aa = ModelFile("aa", True)
        l_aa.remote_size = 3 + 1
        l_a.add_child(l_aa)
        l_aaa = ModelFile("aaa", False)
        l_aaa.remote_size = 1
        l_aa.add_child(l_aaa)
        l_aab = ModelFile("aab", False)
        l_aab.remote_size = 3
        l_aa.add_child(l_aab)
        l_ab = ModelFile("ab", False)
        l_ab.remote_size = 2
        l_a.add_child(l_ab)

        r_a = ModelFile("a", True)
        r_a.remote_size = 3 + 1 + 2
        r_aa = ModelFile("aa", True)
        r_aa.remote_size = 3 + 1
        r_a.add_child(r_aa)
        r_aaa = ModelFile("aaa", False)
        r_aaa.remote_size = 1
        r_aa.add_child(r_aaa)
        r_aab = ModelFile("aab", False)
        r_aab.remote_size = 3
        r_aa.add_child(r_aab)
        r_ab = ModelFile("ab", False)
        r_ab.remote_size = 2
        r_a.add_child(r_ab)

        self.assertEqual(l_a, r_a)

        r_aaa.remote_size = 2
        self.assertNotEqual(l_a, r_a)
Example #14
0
    def test_forwards_extract_commands(self):
        a = ModelFile("a", True)
        a.local_size = 100
        aa = ModelFile("aa", False)
        aa.local_size = 60
        a.add_child(aa)
        ab = ModelFile("ab", False)
        ab.local_size = 40
        a.add_child(ab)

        b = ModelFile("b", True)
        b.local_size = 10
        ba = ModelFile("ba", True)
        ba.local_size = 10
        b.add_child(ba)
        baa = ModelFile("baa", False)
        baa.local_size = 10
        ba.add_child(baa)

        c = ModelFile("c", False)
        c.local_size = 1234

        self.extract_counter = multiprocessing.Value('i', 0)

        def _extract(file: ModelFile):
            print(file.name)
            if self.extract_counter.value == 0:
                self.assertEqual("a", file.name)
                self.assertEqual(True, file.is_dir)
                self.assertEqual(100, file.local_size)
                children = file.get_children()
                self.assertEqual(2, len(children))
                self.assertEqual("aa", children[0].name)
                self.assertEqual(False, children[0].is_dir)
                self.assertEqual(60, children[0].local_size)
                self.assertEqual("ab", children[1].name)
                self.assertEqual(False, children[0].is_dir)
                self.assertEqual(40, children[1].local_size)
            elif self.extract_counter.value == 1:
                self.assertEqual("b", file.name)
                self.assertEqual(True, file.is_dir)
                self.assertEqual(10, file.local_size)
                self.assertEqual(1, len(file.get_children()))
                child = file.get_children()[0]
                self.assertEqual("ba", child.name)
                self.assertEqual(True, child.is_dir)
                self.assertEqual(10, child.local_size)
                self.assertEqual(1, len(child.get_children()))
                subchild = child.get_children()[0]
                self.assertEqual("baa", subchild.name)
                self.assertEqual(False, subchild.is_dir)
                self.assertEqual(10, subchild.local_size)
            elif self.extract_counter.value == 2:
                self.assertEqual("c", file.name)
                self.assertEqual(False, file.is_dir)
                self.assertEqual(1234, file.local_size)
            self.extract_counter.value += 1

        self.mock_dispatch.extract.side_effect = _extract

        self.process = ExtractProcess(out_dir_path="", local_path="")
        self.process.start()

        self.process.extract(a)
        time.sleep(1)
        self.process.extract(b)
        self.process.extract(c)
        while self.extract_counter.value < 3:
            pass