def getInstalledProductStatus(product_directory, entitlement_directory, facts=None): """ Returns the Installed products and their subscription states """ # allow us to stub this out for testing if facts is None: facts = Facts().get_facts() product_status = [] sorter = CertSorter(product_directory, entitlement_directory, facts) for installed_product in sorter.installed_products: product_cert = sorter.installed_products[installed_product] for product in product_cert.products: begin = "" end = "" calculator = ValidProductDateRangeCalculator(sorter) prod_status_range = calculator.calculate(product.id) if prod_status_range: # Format the date in user's local time as the date # range is returned in GMT. begin = formatDate(prod_status_range.begin()) end = formatDate(prod_status_range.end()) data = (product.name, installed_product, product.version, ",".join(product.architectures), sorter.get_status(product.id), begin, end) product_status.append(data) return product_status
def test_consider_invalid_gap_between_non_stacked_entitlement(self): start1 = self.NOW - self.THREE_MONTHS end1 = start1 + self.ONE_MONTH start2 = end1 - self.TEN_DAYS end2 = start2 + self.THREE_MONTHS start3 = start2 + self.ONE_MONTH end3 = start3 + self.THREE_MONTHS installed = create_prod_cert(self.INST_PID_1) ent1 = self._create_entitlement(self.INST_PID_1, start1, end1) partial_ent_1 = stub_ent_cert(self.INST_PID_2, [self.INST_PID_1], quantity=1, stack_id=self.STACK_1, sockets=2, start_date=start2, end_date=end2) ent3 = self._create_entitlement(self.INST_PID_1, start3, end3) ents = [ent1, partial_ent_1, ent3] sorter = create_cert_sorter([installed], ents, machine_sockets=4) self.assertEqual(SUBSCRIBED, sorter.get_status(self.INST_PID_1)) calculator = ValidProductDateRangeCalculator(sorter) valid_range = calculator.calculate(self.INST_PID_1) self.assertNotEqual(None, valid_range) self.assertEquals(start3.replace(tzinfo=GMT()), valid_range.begin()) self.assertEquals(end3.replace(tzinfo=GMT()), valid_range.end())
def test_end_date_set_to_first_date_of_non_compliance_when_stacked(self): installed = create_prod_cert(self.INST_PID_1) start1 = self.NOW - self.THREE_MONTHS end1 = self.NOW + self.THREE_MONTHS start2 = self.NOW - self.ONE_MONTH end2 = self.NOW + self.YEAR start3 = start1 + self.ONE_MONTH end3 = self.NOW - self.TEN_DAYS start4 = end1 end4 = end2 + self.ONE_MONTH partial_ent_1 = stub_ent_cert( self.INST_PID_2, [self.INST_PID_1], quantity=1, stack_id=self.STACK_1, sockets=2, start_date=start1, end_date=end1, ) partial_ent_2 = stub_ent_cert( self.INST_PID_2, [self.INST_PID_1], quantity=1, stack_id=self.STACK_1, sockets=2, start_date=start2, end_date=end2, ) partial_ent_3 = stub_ent_cert( self.INST_PID_2, [self.INST_PID_1], quantity=1, stack_id=self.STACK_1, sockets=2, start_date=start3, end_date=end3, ) partial_ent_4 = stub_ent_cert( self.INST_PID_2, [self.INST_PID_1], quantity=1, stack_id=self.STACK_1, sockets=2, start_date=start4, end_date=end4, ) ents = [partial_ent_1, partial_ent_2, partial_ent_3, partial_ent_4] sorter = create_cert_sorter([installed], ents, machine_sockets=4) self.assertEqual(SUBSCRIBED, sorter.get_status(self.INST_PID_1)) calculator = ValidProductDateRangeCalculator(sorter) valid_range = calculator.calculate(self.INST_PID_1) self.assertNotEqual(None, valid_range) self.assertEquals(start3.replace(tzinfo=GMT()), valid_range.begin()) self.assertEquals(end2.replace(tzinfo=GMT()), valid_range.end())
def test_only_future_entitlement_returns_none(self): expected_begin_date = self.NOW + self.ONE_MONTH expected_end_date = self.NOW + self.THREE_MONTHS installed = create_prod_cert(self.INST_PID_1) ent = self._create_entitlement(self.INST_PID_1, expected_begin_date, expected_end_date) sorter = create_cert_sorter([installed], [ent]) calculator = ValidProductDateRangeCalculator(sorter) prod_range = calculator.calculate(self.INST_PID_1) self.assertEquals(None, prod_range)
def test_only_expired_entitlement_returns_none(self): expected_start = self.NOW - self.YEAR expected_end = self.NOW - self.ONE_MONTH installed = create_prod_cert(self.INST_PID_1) ent = self._create_entitlement(self.INST_PID_1, expected_start, expected_end) sorter = create_cert_sorter([installed], [ent]) calculator = ValidProductDateRangeCalculator(sorter) prod_range = calculator.calculate(self.INST_PID_1) self.assertEquals(None, prod_range)
class ValidProductDateRangeCalculatorTests(SubManFixture): def setUp(self): SubManFixture.setUp(self) self.status = json.loads(INST_PROD_STATUS)['installedProducts'] self.prod_status_cache = NonCallableMock() self.prod_status_cache.load_status = Mock(return_value=self.status) inj.provide(inj.PROD_STATUS_CACHE, self.prod_status_cache) self.calculator = ValidProductDateRangeCalculator(None) # If client asks for product status for something server doesn't # know is installed, this is very weird, but we will log and handle # gracefully: def test_installed_product_mismatch(self): self.assertTrue(self.calculator.calculate('NOTTHERE') is None) # Very old servers may not expose product date ranges: def test_missing_installed_status(self): for prod in self.status: prod.pop('startDate') prod.pop('endDate') for pid in (INST_PID_1, INST_PID_2, INST_PID_3): self.assertTrue(self.calculator.calculate(pid) is None) def test_product_with_status(self): #"startDate" : "2013-02-26T00:00:00.000+0000", #"endDate" : "2014-02-26T00:00:00.000+0000" date_range = self.calculator.calculate(INST_PID_1) self.assertEquals(datetime(2013, 02, 26, 0, 0, 0, 0, GMT()), date_range.begin()) self.assertEquals(datetime(2014, 02, 26, 0, 0, 0, 0, GMT()), date_range.end()) def test_product_without_status(self): self.assertTrue(self.calculator.calculate(INST_PID_3) is None) def test_unregistered(self): id_mock = NonCallableMock() id_mock.is_valid.return_value = False inj.provide(inj.IDENTITY, id_mock) self.calculator = ValidProductDateRangeCalculator(None) for pid in (INST_PID_1, INST_PID_2, INST_PID_3): self.assertTrue(self.calculator.calculate(pid) is None)
def test_single_entitlement(self): expected_begin_date = self.NOW - self.ONE_MONTH expected_end_date = self.NOW + self.ONE_MONTH installed = create_prod_cert(self.INST_PID_1) ent = self._create_entitlement(self.INST_PID_1, expected_begin_date, expected_end_date) sorter = create_cert_sorter([installed], [ent]) calculator = ValidProductDateRangeCalculator(sorter) prod_range = calculator.calculate(self.INST_PID_1) self.assertEquals(expected_begin_date.replace(tzinfo=GMT()), prod_range.begin()) self.assertEquals(expected_end_date.replace(tzinfo=GMT()), prod_range.end())
def test_partial_has_no_date_range_calculated(self): installed = create_prod_cert(self.INST_PID_1) start = self.NOW end = self.NOW + self.YEAR partial_ent = stub_ent_cert(self.INST_PID_2, [self.INST_PID_1], quantity=1, stack_id=self.STACK_1, sockets=2, start_date=start, end_date=end) sorter = create_cert_sorter([installed], [partial_ent]) self.assertEqual(PARTIALLY_SUBSCRIBED, sorter.get_status(self.INST_PID_1)) calculator = ValidProductDateRangeCalculator(sorter) valid_range = calculator.calculate(self.INST_PID_1) self.assertEquals(None, valid_range)
def test_multiple_entitlements_expired_with_overlap(self): expected_start = self.NOW - self.YEAR expected_end = self.NOW + self.YEAR installed = create_prod_cert(self.INST_PID_1) ent1 = self._create_entitlement(self.INST_PID_1, self.NOW - self.THREE_MONTHS, expected_end) ent2 = self._create_entitlement(self.INST_PID_1, expected_start, self.NOW - self.ONE_MONTH) sorter = create_cert_sorter([installed], [ent1, ent2]) calculator = ValidProductDateRangeCalculator(sorter) prod_range = calculator.calculate(self.INST_PID_1) self.assertEquals(expected_start.replace(tzinfo=GMT()), prod_range.begin()) self.assertEquals(expected_end.replace(tzinfo=GMT()), prod_range.end())
def test_multiple_entitlements_one_consumes_other(self): expected_start = self.NOW - self.THREE_MONTHS expected_end = self.NOW + self.YEAR installed = create_prod_cert(self.INST_PID_1) ent1 = self._create_entitlement(self.INST_PID_1, self.NOW - self.ONE_MONTH, self.NOW + self.THREE_MONTHS) ent2 = self._create_entitlement(self.INST_PID_1, expected_start, expected_end) sorter = create_cert_sorter([installed], [ent1, ent2]) calculator = ValidProductDateRangeCalculator(sorter) prod_range = calculator.calculate(self.INST_PID_1) self.assertEquals(expected_start.replace(tzinfo=GMT()), prod_range.begin()) self.assertEquals(expected_end.replace(tzinfo=GMT()), prod_range.end())
def test_non_stacking_entitlements(self): start1 = self.NOW - self.THREE_MONTHS end1 = self.NOW + self.THREE_MONTHS start2 = self.NOW - self.ONE_MONTH end2 = self.NOW + self.YEAR installed = create_prod_cert(self.INST_PID_1) ent1 = self._create_entitlement(self.INST_PID_1, start1, end1, sockets=4, quantity=2) ent2 = self._create_entitlement(self.INST_PID_1, start2, end2, sockets=4) sorter = create_cert_sorter([installed], [ent1, ent2]) calculator = ValidProductDateRangeCalculator(sorter) prod_range = calculator.calculate(self.INST_PID_1) self.assertTrue(prod_range is None)
def test_entitlements_with_overlap(self): start1 = self.NOW - self.TEN_MINUTES end1 = self.NOW + self.THIRTY_MINUTES start2 = self.NOW - self.THIRTY_MINUTES end2 = self.NOW + self.TEN_MINUTES installed = create_prod_cert(self.INST_PID_1) ent1 = self._create_entitlement(self.INST_PID_1, start1, end1, sockets=1) ent2 = self._create_entitlement(self.INST_PID_1, start2, end2, sockets=1) sorter = create_cert_sorter([installed], [ent1, ent2], machine_sockets=1) calculator = ValidProductDateRangeCalculator(sorter) prod_range = calculator.calculate(self.INST_PID_1) self.assertFalse(prod_range is None)
def test_end_date_set_to_first_date_of_non_compliance_when_stacked(self): installed = create_prod_cert(self.INST_PID_1) start1 = self.NOW - self.THREE_MONTHS end1 = self.NOW + self.THREE_MONTHS start2 = self.NOW - self.ONE_MONTH end2 = self.NOW + self.YEAR start3 = start1 + self.ONE_MONTH end3 = self.NOW - self.TEN_DAYS start4 = end1 end4 = end2 + self.ONE_MONTH partial_ent_1 = stub_ent_cert(self.INST_PID_2, [self.INST_PID_1], quantity=1, stack_id=self.STACK_1, sockets=2, start_date=start1, end_date=end1) partial_ent_2 = stub_ent_cert(self.INST_PID_2, [self.INST_PID_1], quantity=1, stack_id=self.STACK_1, sockets=2, start_date=start2, end_date=end2) partial_ent_3 = stub_ent_cert(self.INST_PID_2, [self.INST_PID_1], quantity=1, stack_id=self.STACK_1, sockets=2, start_date=start3, end_date=end3) partial_ent_4 = stub_ent_cert(self.INST_PID_2, [self.INST_PID_1], quantity=1, stack_id=self.STACK_1, sockets=2, start_date=start4, end_date=end4) ents = [partial_ent_1, partial_ent_2, partial_ent_3, partial_ent_4] sorter = create_cert_sorter([installed], ents, machine_sockets=4) self.assertEqual(SUBSCRIBED, sorter.get_status(self.INST_PID_1)) calculator = ValidProductDateRangeCalculator(sorter) valid_range = calculator.calculate(self.INST_PID_1) self.assertNotEqual(None, valid_range) self.assertEquals(start3.replace(tzinfo=GMT()), valid_range.begin()) self.assertEquals(end2.replace(tzinfo=GMT()), valid_range.end())
def test_single_entitlement_ignores_future_with_no_overlap(self): expected_begin_date = self.NOW - self.ONE_MONTH expected_end_date = self.NOW + self.ONE_MONTH installed = create_prod_cert(self.INST_PID_1) ent = self._create_entitlement(self.INST_PID_1, expected_begin_date, expected_end_date) future_start = expected_begin_date + self.THREE_MONTHS future = self._create_entitlement(self.INST_PID_1, future_start, future_start + self.YEAR) sorter = create_cert_sorter([installed], [ent, future]) calculator = ValidProductDateRangeCalculator(sorter) prod_range = calculator.calculate(self.INST_PID_1) self.assertEquals(expected_begin_date.replace(tzinfo=GMT()), prod_range.begin()) self.assertEquals(expected_end_date.replace(tzinfo=GMT()), prod_range.end())
def getInstalledProductStatus(product_directory=None, entitlement_directory=None, facts=None): """ Returns the Installed products and their subscription states """ # allow us to stub these out for testing if product_directory is None: product_directory = certdirectory.ProductDirectory() if entitlement_directory is None: entitlement_directory = certdirectory.EntitlementDirectory() if facts is None: facts = Facts().get_facts() product_status = [] sorter = CertSorter(product_directory, entitlement_directory, facts) for installed_product in sorter.installed_products: product_cert = sorter.installed_products[installed_product] for product in product_cert.getProducts(): begin = "" end = "" calculator = ValidProductDateRangeCalculator(sorter) prod_status_range = calculator.calculate(product.getHash()) if prod_status_range: # Format the date in user's local time as the date # range is returned in GMT. begin = formatDate(prod_status_range.begin()) end = formatDate(prod_status_range.end()) data = (product.getName(), installed_product, product.getVersion(), product.getArch(), sorter.get_status(product.getHash()), begin, end) product_status.append(data) return product_status
def update_products(self): self.store.clear() self.cs = cert_sorter.CertSorter(self.product_dir, self.entitlement_dir, self.facts.get_facts()) for product_cert in self.product_dir.list(): for product in product_cert.getProducts(): product_id = product.getHash() status = self.cs.get_status(product_id) entry = {} entry['product'] = product.getName() entry['version'] = product.getVersion() entry['arch'] = product.getArch() entry['product_id'] = product_id # Common properties entry['align'] = 0.5 # TODO: Pull this date logic out into a separate lib! # This is also used in mysubstab... if status != NOT_SUBSCRIBED: range_calculator = ValidProductDateRangeCalculator(self.cs) compliant_range = range_calculator.calculate(product.getHash()) start = '' end = '' if compliant_range: start = compliant_range.begin() end = compliant_range.end() contract_ids, sub_names = self._calc_subs_providing( product_id, compliant_range) name = ", ".join(sub_names) contract = ", ".join(contract_ids) entry['subscription'] = name entry['start_date'] = start entry['expiration_date'] = end if status == FUTURE_SUBSCRIBED: entry['image'] = self._render_icon('red') entry['status'] = _('Future Subscription') entry['validity_note'] = _("Future Subscribed") elif status == EXPIRED: entry['image'] = self._render_icon('red') entry['status'] = _('Expired') sub_numbers = set([]) for ent_cert in self.cs.get_entitlements_for_product(product_id): order = ent_cert.getOrder() # FIXME: getSubscription() seems to always be None...? if order.getSubscription(): sub_numbers.add(order.getSubscription()) subs_str = ', '.join(sub_numbers) entry['validity_note'] = \ _('Subscription %s is expired') % subs_str elif status == PARTIALLY_SUBSCRIBED: entry['image'] = self._render_icon('yellow') entry['status'] = _('Partially Subscribed') entry['validity_note'] = _("Partially Subscribed") else: entry['image'] = self._render_icon('green') entry['status'] = _('Subscribed') entry['validity_note'] = \ _('Covered by contract(s) %s through %s') % \ (contract, managerlib.formatDate(entry['expiration_date'])) else: entry['image'] = self._render_icon('red') entry['status'] = _('Not Subscribed') entry['validity_note'] = _("Not Subscribed") self.store.add_map(entry) # 811340: Select the first product in My Installed Software # table by default. selection = self.top_view.get_selection() selection.select_path(0)
def update_products(self): self.store.clear() self.cs = cert_sorter.CertSorter(self.product_dir, self.entitlement_dir, self.facts.get_facts()) for product_cert in self.product_dir.list(): for product in product_cert.getProducts(): product_id = product.getHash() status = self.cs.get_status(product_id) entry = {} entry['product'] = product.getName() entry['version'] = product.getVersion() entry['arch'] = product.getArch() entry['product_id'] = product_id # Common properties entry['align'] = 0.5 # TODO: Pull this date logic out into a separate lib! # This is also used in mysubstab... if status != NOT_SUBSCRIBED: range_calculator = ValidProductDateRangeCalculator(self.cs) compliant_range = range_calculator.calculate( product.getHash()) start = '' end = '' if compliant_range: start = compliant_range.begin() end = compliant_range.end() contract_ids, sub_names = self._calc_subs_providing( product_id, compliant_range) name = ", ".join(sub_names) contract = ", ".join(contract_ids) entry['subscription'] = name entry['start_date'] = start entry['expiration_date'] = end if status == FUTURE_SUBSCRIBED: entry['image'] = self._render_icon('red') entry['status'] = _('Future Subscription') entry['validity_note'] = _("Future Subscribed") elif status == EXPIRED: entry['image'] = self._render_icon('red') entry['status'] = _('Expired') sub_numbers = set([]) for ent_cert in self.cs.get_entitlements_for_product( product_id): order = ent_cert.getOrder() # FIXME: getSubscription() seems to always be None...? if order.getSubscription(): sub_numbers.add(order.getSubscription()) subs_str = ', '.join(sub_numbers) entry['validity_note'] = \ _('Subscription %s is expired') % subs_str elif status == PARTIALLY_SUBSCRIBED: entry['image'] = self._render_icon('yellow') entry['status'] = _('Partially Subscribed') entry['validity_note'] = _("Partially Subscribed") else: entry['image'] = self._render_icon('green') entry['status'] = _('Subscribed') entry['validity_note'] = \ _('Covered by contract(s) %s through %s') % \ (contract, managerlib.formatDate(entry['expiration_date'])) else: entry['image'] = self._render_icon('red') entry['status'] = _('Not Subscribed') entry['validity_note'] = _("Not Subscribed") self.store.add_map(entry) # 811340: Select the first product in My Installed Software # table by default. selection = self.top_view.get_selection() selection.select_path(0)