def test_partial_stack_for_uninstalled_products(self):
        # No products installed:
        prod_dir = StubCertificateDirectory([])

        stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 42})
        ents = []
        ents.append(
            stub_ent_cert(INST_PID_5, ['prod1'], stack_id=STACK_1, quantity=2))
        ent_dir = StubCertificateDirectory(ents)
        sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts())

        # No installed products, so nothing should show up as partially valid:
        self.assertEquals(0, len(sorter.partially_valid_products))

        self.assertEquals(1, len(sorter.partial_stacks))
        self.assertTrue(STACK_1 in sorter.partial_stacks)
        self.assertFalse(sorter.is_valid())
    def test_partial_stack_for_uninstalled_products(self):
        # No products installed:
        prod_dir = StubCertificateDirectory([])

        stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 42})
        ents = []
        ents.append(stub_ent_cert(INST_PID_5, ['prod1'],
            stack_id=STACK_1, quantity=2))
        ent_dir = StubCertificateDirectory(ents)
        sorter = CertSorter(prod_dir, ent_dir,
                stub_facts.get_facts())

        # No installed products, so nothing should show up as partially valid:
        self.assertEquals(0, len(sorter.partially_valid_products))

        self.assertEquals(1, len(sorter.partial_stacks))
        self.assertTrue(STACK_1 in sorter.partial_stacks)
        self.assertFalse(sorter.is_valid())
class CertSorterTests(unittest.TestCase):

    def setUp(self):
        # Setup mock product and entitlement certs:
        self.prod_dir = StubCertificateDirectory([
            # Will be unentitled:
            StubProductCertificate(StubProduct(INST_PID_1)),
            # Will be entitled:
            StubProductCertificate(StubProduct(INST_PID_2)),
            # Will be entitled but expired:
            StubProductCertificate(StubProduct(INST_PID_3)),
        ])

        self.ent_dir = StubEntitlementDirectory([
            StubEntitlementCertificate(StubProduct(INST_PID_2)),
            StubEntitlementCertificate(StubProduct(INST_PID_3),
                start_date=datetime.now() - timedelta(days=365),
                end_date=datetime.now() - timedelta(days=2)),
            StubEntitlementCertificate(StubProduct(INST_PID_4),
                start_date=datetime.now() - timedelta(days=365),
                end_date=datetime.now() + timedelta(days=365)),
            StubEntitlementCertificate(StubProduct(INST_PID_5)),
            # entitled, but not installed
            StubEntitlementCertificate(StubProduct('not_installed_product')),
            ])

    def test_unentitled_product_certs(self):
        self.sorter = CertSorter(self.prod_dir, self.ent_dir, {})
        self.assertEqual(1, len(self.sorter.unentitled_products.keys()))
        self.assertTrue(INST_PID_1 in self.sorter.unentitled_products)
        self.assertFalse(self.sorter.is_valid())
        self.assertEqual(NOT_SUBSCRIBED, self.sorter.get_status(INST_PID_1))

    def test_ent_cert_no_installed_product(self):
        self.sorter = CertSorter(self.prod_dir, self.ent_dir, {})
        # TODO: looks like this test was never completed

    def test_ent_cert_no_product(self):
        self.ent_dir = StubCertificateDirectory(
            [StubEntitlementCertificate(None, provided_products=[],
                                        quantity=2)])

        stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 42})
        self.sorter = CertSorter(self.prod_dir, self.ent_dir,
                stub_facts.get_facts())

        self.assertEqual(0, len(self.sorter.partially_valid_products))

    def test_expired(self):
        self.sorter = CertSorter(self.prod_dir, self.ent_dir, {})
        self.assertEqual(1, len(self.sorter.expired_entitlement_certs))

        self.assertTrue(cert_list_has_product(
            self.sorter.expired_entitlement_certs, INST_PID_3))

        self.assertEqual(1, len(self.sorter.expired_products.keys()))
        self.assertTrue(INST_PID_3 in self.sorter.expired_products)
        self.assertFalse(self.sorter.is_valid())
        self.assertEquals(EXPIRED, self.sorter.get_status(INST_PID_3))

    def test_expired_in_future(self):
        self.sorter = CertSorter(self.prod_dir, self.ent_dir, {},
                on_date=datetime(2050, 1, 1, tzinfo=GMT()))
        self.assertEqual(5, len(self.sorter.expired_entitlement_certs))
        self.assertTrue(INST_PID_2 in self.sorter.expired_products)
        self.assertTrue(INST_PID_3 in self.sorter.expired_products)
        self.assertFalse(INST_PID_4 in self.sorter.expired_products)  # it's not installed
        self.assertTrue(INST_PID_1 in self.sorter.unentitled_products)
        self.assertEqual(0, len(self.sorter.valid_entitlement_certs))
        self.assertFalse(self.sorter.is_valid())

    def test_entitled_products(self):
        provided = [StubProduct(INST_PID_1), StubProduct(INST_PID_2),
                StubProduct(INST_PID_3)]
        self.ent_dir = StubCertificateDirectory([
            StubEntitlementCertificate(StubProduct(INST_PID_5),
                provided_products=provided)])
        self.sorter = CertSorter(self.prod_dir, self.ent_dir, {})
        self.assertEquals(3, len(self.sorter.valid_products.keys()))
        self.assertTrue(INST_PID_1 not in self.sorter.partially_valid_products)
        self.assertTrue(INST_PID_1 in self.sorter.valid_products)
        self.assertTrue(INST_PID_2 in self.sorter.valid_products)
        self.assertTrue(INST_PID_3 in self.sorter.valid_products)
        self.assertTrue(self.sorter.is_valid())

    def test_expired_but_provided_in_another_entitlement(self):
        self.ent_dir = StubCertificateDirectory([
            StubEntitlementCertificate(StubProduct(INST_PID_5),
                provided_products=[StubProduct(INST_PID_3)]),
            StubEntitlementCertificate(StubProduct(INST_PID_5),
                start_date=datetime.now() - timedelta(days=365),
                end_date=datetime.now() - timedelta(days=2),
                provided_products=[StubProduct(INST_PID_3)]),
            StubEntitlementCertificate(StubProduct(INST_PID_4))
        ])
        self.sorter = CertSorter(self.prod_dir, self.ent_dir, {})
        self.assertEquals(1, len(self.sorter.valid_products.keys()))
        self.assertTrue(INST_PID_3 in self.sorter.valid_products)
        self.assertEquals(0, len(self.sorter.expired_products.keys()))

    def test_multi_product_entitlement_expired(self):
        # Setup one ent cert that provides several things installed
        # installed:
        provided = [StubProduct(INST_PID_2), StubProduct(INST_PID_3)]
        self.ent_dir = StubCertificateDirectory([
            StubEntitlementCertificate(StubProduct(INST_PID_5),
                provided_products=provided)])
        self.sorter = CertSorter(self.prod_dir, self.ent_dir, {},
                on_date=datetime(2050, 1, 1, tzinfo=GMT()))

        self.assertEquals(1, len(self.sorter.expired_entitlement_certs))
        self.assertEquals(2, len(self.sorter.expired_products.keys()))
        self.assertTrue(INST_PID_2 in self.sorter.expired_products)
        self.assertTrue(INST_PID_3 in self.sorter.expired_products)

        # Expired should not show up as unentitled also:
        self.assertEquals(1, len(self.sorter.unentitled_products.keys()))
        self.assertTrue(INST_PID_1 in self.sorter.unentitled_products)
        self.assertFalse(self.sorter.is_valid())

    def test_future_entitled(self):
        provided = [StubProduct(INST_PID_2), StubProduct(INST_PID_3)]
        self.ent_dir = StubCertificateDirectory([
            StubEntitlementCertificate(StubProduct(INST_PID_5),
                provided_products=provided,
                start_date=datetime.now() + timedelta(days=30),
                end_date=datetime.now() + timedelta(days=120)),
            ])

        self.sorter = CertSorter(self.prod_dir, self.ent_dir, {})

        self.assertEquals(0, len(self.sorter.valid_products))
        self.assertEquals(2, len(self.sorter.future_products))
        self.assertEquals(3, len(self.sorter.unentitled_products))
        self.assertTrue(INST_PID_2 in self.sorter.future_products)
        self.assertTrue(INST_PID_3 in self.sorter.future_products)
        self.assertEquals(FUTURE_SUBSCRIBED, self.sorter.get_status(INST_PID_2))
        self.assertEquals(FUTURE_SUBSCRIBED, self.sorter.get_status(INST_PID_3))

    def test_future_and_currently_entitled(self):
        provided = [StubProduct(INST_PID_2), StubProduct(INST_PID_3)]
        self.ent_dir = StubCertificateDirectory([
            StubEntitlementCertificate(StubProduct(INST_PID_5),
                provided_products=provided,
                start_date=datetime.now() + timedelta(days=30),
                end_date=datetime.now() + timedelta(days=120)),
            StubEntitlementCertificate(StubProduct(INST_PID_5),
                provided_products=provided),
            ])

        self.sorter = CertSorter(self.prod_dir, self.ent_dir, {})

        self.assertEquals(2, len(self.sorter.valid_products))
        self.assertEquals(2, len(self.sorter.future_products))
        self.assertEquals(1, len(self.sorter.unentitled_products))
        self.assertTrue(INST_PID_2 in self.sorter.future_products)
        self.assertTrue(INST_PID_3 in self.sorter.future_products)
        self.assertTrue(INST_PID_2 in self.sorter.valid_products)
        self.assertTrue(INST_PID_3 in self.sorter.valid_products)
        self.assertEquals(SUBSCRIBED, self.sorter.get_status(INST_PID_2))
        self.assertEquals(SUBSCRIBED, self.sorter.get_status(INST_PID_3))

    def test_non_stacked_lacking_sockets(self):
        prod_dir = StubCertificateDirectory([stub_prod_cert(INST_PID_1)])
        # System has 8 sockets:
        stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 8})
        # Only 2 sockets covered by a non-stacked entitlement:
        ent_dir = StubCertificateDirectory([
            stub_ent_cert(INST_PID_5, [INST_PID_1], sockets=2,
            quantity=5)])
        sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts())

        self.assertFalse(INST_PID_1 in sorter.unentitled_products)
        self.assertFalse(INST_PID_1 in sorter.valid_products)
        self.assertTrue(INST_PID_1 in sorter.partially_valid_products)
        self.assertEquals(1, len(sorter.partially_valid_products))
        self.assertEquals(1, len(sorter.partially_valid_products[INST_PID_1]))

    def test_non_stacked_0_sockets(self):
        prod_dir = StubCertificateDirectory([stub_prod_cert(INST_PID_1)])
        # System has 8 sockets:
        stub_facts = StubFacts(fact_dict={"cpu.cpu_socket(s)": 8})
        # 0 sockets is basically "unlimited" sockets
        # see bz#805415
        ent_dir = StubCertificateDirectory([
            stub_ent_cert(INST_PID_5, [INST_PID_1], sockets=0,
            quantity=5)])
        sorter = CertSorter(prod_dir, ent_dir, stub_facts.get_facts())

        self.assertFalse(INST_PID_1 in sorter.partially_valid_products)
        self.assertTrue(INST_PID_1 in sorter.valid_products)
        self.assertFalse(INST_PID_1 in sorter.unentitled_products)