Ejemplo n.º 1
0
    def testGetWithWorkingHours(self):
        """Tests get() outside of working hours."""
        old = datetime.datetime(2014, 12, 10, 20, 00, 00, 000000)
        now = datetime.datetime(2016, 9, 12, 0, 00, 00, 000000)

        with mock.patch.object(datetime, 'datetime') as datetime_mock:
            datetime_mock.utcnow.return_value = old
            u1 = models.AppleSUSProduct(tracks=['unstable'],
                                        product_id='fooid1',
                                        manual_override=False)
            u1.put()
            u2 = models.AppleSUSProduct(
                tracks=['unstable', applesus.common.TESTING],
                product_id='fooid3',
                manual_override=False)
            u2.put()

        with mock.patch.object(applesus.AppleSUSCatalogSync,
                               '_DeprecateOrphanedProducts'):
            self.auto_promote.get(now=now)

        u1 = models.AppleSUSProduct.get(u1.key())
        u2 = models.AppleSUSProduct.get(u2.key())
        self.assertTrue(applesus.common.TESTING not in u1.tracks)
        self.assertTrue(applesus.common.STABLE not in u2.tracks)
Ejemplo n.º 2
0
    def testGet(self, _):
        """Tests get() within working hours."""
        old = datetime.datetime(2014, 12, 10, 20, 00, 00, 000000)
        now = datetime.datetime(2016, 9, 10, 11, 00, 00, 000000)

        with mock.patch.object(datetime, 'datetime') as datetime_mock:
            datetime_mock.utcnow.return_value = old
            promote_testing_product = models.AppleSUSProduct(
                tracks=['unstable'], product_id='fooid', manual_override=False)
            promote_testing_product.put()

            promote_stable_product = models.AppleSUSProduct(
                tracks=['unstable', applesus.common.TESTING],
                product_id='fooid3',
                manual_override=False)
            promote_stable_product.put()

        toonew_product = models.AppleSUSProduct(tracks=['unstable'],
                                                product_id='fooid2',
                                                manual_override=False)
        toonew_product.put()

        with mock.patch.object(
                applesus.applesus,
                'GenerateAppleSUSCatalogs') as generate_catalog_mock:
            with mock.patch.object(
                    self.auto_promote,
                    '_NotifyAdminsOfAutoPromotions') as notify_mock:
                self.auto_promote.get(now=now)

                notify_mock.assert_called_once()
                generate_catalog_mock.assert_has_calls([
                    mock.call(applesus.common.TESTING),
                    mock.call(applesus.common.STABLE)
                ],
                                                       any_order=True)

        self.assertEqual(
            2, len(applesus.models.AdminAppleSUSProductLog.all().fetch(None)))

        promote_stable_product = models.AppleSUSProduct.get(
            promote_stable_product.key())
        promote_testing_product = models.AppleSUSProduct.get(
            promote_testing_product.key())
        toonew_product = models.AppleSUSProduct.get(toonew_product.key())

        self.assertTrue(
            applesus.common.TESTING in promote_testing_product.tracks)
        self.assertTrue(
            applesus.common.STABLE not in promote_testing_product.tracks)

        self.assertTrue(applesus.common.TESTING not in toonew_product.tracks)
        self.assertTrue(applesus.common.STABLE not in toonew_product.tracks)

        self.assertTrue(
            applesus.common.STABLE in promote_stable_product.tracks)
Ejemplo n.º 3
0
    def testChangeProductForceInstall(self, *_):
        product_id = 'pid'
        models.AppleSUSProduct(key_name=product_id,
                               product_id=product_id,
                               manual_override=False).put()

        force_install_after_date = (datetime.datetime.now() +
                                    datetime.timedelta(days=4))

        self.testapp.post('/admin/applesus/product/' + product_id, {
            'force_install_after_date':
            datetime.datetime.strftime(force_install_after_date,
                                       '%Y-%m-%d %H:%M'),
        },
                          status=httplib.OK)

        product = models.AppleSUSProduct.get_by_key_name(product_id)
        self.assertEquals(
            datetime.datetime.strftime(force_install_after_date,
                                       '%Y-%m-%dT%H:%M:00Z'),
            product.force_install_after_date_str)

        self.RunAllDeferredTasks()

        mail_stub = self.testbed.get_stub('mail')
        messages = mail_stub.get_sent_messages()

        self.assertEqual(1, len(messages))
        self.assertEqual(1,
                         len(models.AdminAppleSUSProductLog.all().fetch(None)))
Ejemplo n.º 4
0
    def testDeprecateOrphanedProducts(self):
        """Tests _DeprecateOrphanedProducts() with deprecated & active products."""
        self.stubs.Set(applesus.applesus, 'OS_VERSIONS',
                       frozenset(['10.9', '10.10', None]))
        self.stubs.Set(applesus.common, 'TRACKS',
                       applesus.common.TRACKS + ['parseerror'])

        for os_version in applesus.applesus.OS_VERSIONS:
            for track in applesus.common.TRACKS + ['untouched']:
                if not os_version:
                    continue
                key = '%s_%s' % (os_version, track)
                applesus.models.AppleSUSCatalog(key_name=key,
                                                plist='fooplist-%s' %
                                                key).put()

        test_products = {
            '10.8_unstable': ['product5', 'product6'],
            '10.8_testing': ['product5'],
            '10.8_stable': ['product5'],
            '10.8_untouched': ['product7'],
            '10.9_unstable': ['product5', 'product6'],
            '10.9_testing': ['product5'],
            '10.9_stable': ['product5'],
            '10.9_untouched': ['product7'],
            '10.10_unstable': ['product1'],
            '10.10_testing': ['product3', 'product4'],
            '10.10_stable': ['product3'],
            '10.10_untouched': ['product7'],
            '10.11_unstable': ['product1'],
            '10.11_testing': ['product3', 'product4'],
            '10.11_stable': ['product3'],
            '10.11_untouched': ['product7'],
        }
        for p in ['product2', 'product3', 'product7', 'deprecateme', 'andme']:
            models.AppleSUSProduct(product_id=p).put()

        def PlistStub(plist):
            m = mock.Mock()
            if 'parseerror' in plist:
                m.Parse.side_effect = applesus.plist.Error
            else:
                prefix = 'fooplist-'
                assert plist.startswith(prefix)
                m.get.return_value = test_products[plist[len(prefix):]]
            return m

        self.stubs.Set(applesus.plist, 'ApplePlist', PlistStub)

        out = self.catalog_sync._DeprecateOrphanedProducts()
        expected_deprecated = ['andme', 'deprecateme', 'product2']
        self.assertEqual(expected_deprecated,
                         sorted(p.product_id for p in out))

        products = models.AppleSUSProduct.all().filter('deprecated =', False)
        self.assertEqual(['product3', 'product7'],
                         sorted(p.product_id for p in products))
Ejemplo n.º 5
0
    def testDisplayUpdateLogs(self, render_mock, _):
        product_id = 'pid'
        p = models.AppleSUSProduct(key_name=product_id,
                                   product_id=product_id,
                                   tracks=['unstable'])
        p.put()
        models.AdminAppleSUSProductLog.Log(p, 'action description')

        self.testapp.get('/admin/applesus/logs', {'product_id': product_id},
                         status=httplib.OK)

        args = test.GetArgFromCallHistory(render_mock, arg_index=1)
        self.assertEqual(1, len(args['logs']))
        self.assertEqual(product_id, args['product_id'])
Ejemplo n.º 6
0
    def testDisplayMain(self, render_mock, _):
        product_id = 'pid'
        models.AppleSUSProduct(key_name=product_id,
                               product_id=product_id,
                               tracks=['unstable']).put()

        self.testapp.get('/admin/applesus/', status=httplib.OK)

        args = test.GetArgFromCallHistory(render_mock, arg_index=1)

        self.assertEqual(1, len(args['products']))
        self.assertLess(args['products'][0].stable_promote_date,
                        (datetime.datetime.now() +
                         datetime.timedelta(days=60)).date())
Ejemplo n.º 7
0
    def testChangeProductForceInstallToday(self, *_):
        product_id = 'pid'
        models.AppleSUSProduct(key_name=product_id,
                               product_id=product_id,
                               manual_override=False).put()

        force_install_after_date = datetime.datetime.now()

        self.testapp.post('/admin/applesus/product/' + product_id, {
            'force_install_after_date':
            datetime.datetime.strftime(force_install_after_date,
                                       '%Y-%m-%d %H:%M'),
        },
                          status=httplib.BAD_REQUEST)
Ejemplo n.º 8
0
    def testChangeProductManualOverride(self, *_):
        product_id = 'pid'
        models.AppleSUSProduct(key_name=product_id,
                               product_id=product_id,
                               manual_override=False).put()

        self.testapp.post('/admin/applesus/product/' + product_id, {
            'manual_override': 1,
        },
                          status=httplib.OK)

        product = models.AppleSUSProduct.get_by_key_name(product_id)
        self.assertTrue(product.manual_override)

        self.RunAllDeferredTasks()

        mail_stub = self.testbed.get_stub('mail')
        messages = mail_stub.get_sent_messages()

        self.assertEqual(1, len(messages))

        self.assertEqual(1,
                         len(models.AdminAppleSUSProductLog.all().fetch(None)))
Ejemplo n.º 9
0
    def testChangeProduct(self, *_):
        settings.EMAIL_ON_EVERY_CHANGE = True

        product_id = 'pid'
        models.AppleSUSProduct(key_name=product_id,
                               product_id=product_id).put()

        self.testapp.post('/admin/applesus/product/' + product_id, {
            'enabled': 1,
            'track': 'stable',
        },
                          status=httplib.OK)

        product = models.AppleSUSProduct.get_by_key_name(product_id)
        self.assertEqual(['stable'], product.tracks)

        self.RunAllDeferredTasks()

        mail_stub = self.testbed.get_stub('mail')
        messages = mail_stub.get_sent_messages()

        self.assertEqual(1, len(messages))
        self.assertEqual('*****@*****.**', messages[0].to)
Ejemplo n.º 10
0
    def testUpdateProductDataFromCatalog(self, urlopen_mock,
                                         dist_file_doc_mock):
        """Tests _UpdateProductDataFromCatalog()."""
        product_one_id = '1productid'
        product_one_url = 'http://example.com/%s.dist' % product_one_id
        product_one_package_url = 'http://example.com/%s.pkg' % product_one_id
        product_two_id = '2productid'
        product_two_url = 'http://example.com/%s.dist' % product_one_id
        product_two_package_url1 = 'http://example.com/%s-1.pkg' % product_two_id
        product_two_package_url2 = 'http://example.com/%s-2.pkg' % product_two_id
        product_two_dist = {
            'version': 'twover',
            'title': 'twotitle',
            'description': 'twodesc',
            'restart_required': False,
        }
        product_three_id = '3productid'
        product_three_url = 'http://example.com/%s.dist' % product_three_id
        product_three_package_url = 'http://example.com/%s.pkg' % product_three_id
        product_three_dist = {
            'version': 'threever',
            'title': 'threetitle',
            'description': 'threedesc',
            'restart_required': True,
        }
        onedate = datetime.datetime(2014, 10, 8, 20, 00, 00, 000000)
        twodate = datetime.datetime(2015, 10, 8, 12, 00, 00, 000000)
        threedate = datetime.datetime(2013, 10, 8, 3, 00, 00, 000000)
        catalog = {
            'Products': {
                product_one_id: {
                    'Distributions': {
                        'English': product_one_url
                    },
                    'PostDate': onedate,
                    'Packages': [{
                        'URL': [product_one_package_url]
                    }],
                },
                product_two_id: {
                    'Distributions': {
                        'English': product_two_url
                    },
                    'PostDate':
                    twodate,
                    'Packages': [{
                        'URL': product_two_package_url1
                    }, {
                        'URL': product_two_package_url2
                    }],
                },
                product_three_id: {
                    'Distributions': {
                        'en': product_three_url
                    },
                    'PostDate': threedate,
                    'Packages': [{
                        'URL': product_three_package_url
                    }],
                },
            }
        }

        mock_urllib_return = mock.Mock()
        mock_urllib_return.code = httplib.OK  # always return 200 for test.
        mock_urllib_return.read.side_effect = [
            product_two_dist, product_three_dist
        ]
        urlopen_mock.return_value = mock_urllib_return

        # product_one; add to existing_products so it's skipped.
        models.AppleSUSProduct(product_id=product_one_id).put()

        # product_two
        mock_dfd_two = mock.Mock()
        for k, v in product_two_dist.iteritems():
            setattr(mock_dfd_two, k, v)
        # product_three
        mock_dfd_three = mock.Mock()
        for k, v in product_three_dist.iteritems():
            setattr(mock_dfd_three, k, v)

        dist_file_doc_mock.side_effect = [mock_dfd_two, mock_dfd_three]

        new_products = self.catalog_sync._UpdateProductDataFromCatalog(catalog)

        urlopen_mock.assert_has_calls(
            [mock.call(product_two_url),
             mock.call(product_three_url)],
            any_order=True)

        product_two = models.AppleSUSProduct.all().filter(
            'product_id =', product_two_id).fetch(1)[0]
        product_three = models.AppleSUSProduct.all().filter(
            'product_id =', product_three_id).fetch(1)[0]

        self.assertEqual([product_two_id, product_three_id],
                         [p.product_id for p in new_products])
        self.assertEqual(product_two.name, 'twotitle')
        self.assertEqual(product_two.apple_mtime, twodate)
        self.assertFalse(product_two.restart_required)
        self.assertTrue(product_two.unattended)
        self.assertEqual(product_two.package_urls,
                         [product_two_package_url1, product_two_package_url2])

        self.assertEqual(product_three.version, 'threever')
        self.assertEqual(product_three.description, 'threedesc')
        self.assertTrue(product_three.restart_required)
        self.assertFalse(product_three.unattended)
        self.assertEqual(product_three.package_urls,
                         [product_three_package_url])
Ejemplo n.º 11
0
    def _UpdateProductDataFromCatalog(cls, catalog_plist):
        """Updates models.AppleSUSProduct model from a catalog plist object.

    Args:
      catalog_plist: plist.ApplePlist object.

    Returns:
      list of new models.AppleSUSProduct objects, or empty list.
    """
        if 'Products' not in catalog_plist:
            logging.error('Products not found in Apple Updates catalog')
            return []

        new_products = []

        # Create a dict of all previously processed product IDs for fast lookup.
        existing_products = set()
        products_query = models.AppleSUSProduct.all().filter(
            'deprecated =', False)
        for product in products_query:
            existing_products.add(product.product_id)

        # Loop over all products IDs in the Apple Updates catalog, adding any new
        # products to the models.AppleSUSProduct model.
        catalog_product_keys = catalog_plist.get('Products', {}).keys()
        catalog_product_keys.sort()
        for key in catalog_product_keys:
            if key in existing_products:
                continue  # This product has already been processed in the past.

            # Download and parse distribution metadata.
            distributions = catalog_plist['Products'][key]['Distributions']
            dist_url = distributions.get('English', None) or distributions.get(
                'en', None)
            if not dist_url:
                logging.error(
                    'No english distributions exists for product %s; skipping.',
                    key)
                continue  # No english distribution exists :(
            r = urllib2.urlopen(dist_url)
            if r.code != httplib.OK:
                continue
            dist_str = r.read()
            dist = applesus.DistFileDocument()
            dist.LoadDocument(dist_str)

            product = models.AppleSUSProduct(key_name=key)
            product.product_id = key
            product.name = dist.title
            product.apple_mtime = catalog_plist['Products'][key]['PostDate']
            product.version = dist.version
            product.description = dist.description
            product.tracks = [common.UNSTABLE]
            product.restart_required = dist.restart_required
            if not dist.restart_required and settings.APPLE_AUTO_UNATTENDED_ENABLED:
                product.unattended = True
            else:
                product.unattended = False

            # Parse package download URLs.
            for package in catalog_plist['Products'][key]['Packages']:
                product.package_urls.append(package.get('URL'))

            product.put()
            new_products.append(product)

        return new_products
Ejemplo n.º 12
0
    def _UpdateProductDataFromCatalog(self, catalog_plist):
        """Updates models.AppleSUSProduct model from a catalog plist object.

    Args:
      catalog_plist: plist.ApplePlist object.

    Returns:
      list of new models.AppleSUSProduct objects, or empty list.
    """
        if 'Products' not in catalog_plist:
            logging.error('Products not found in Apple Updates catalog')
            return []

        new_products = []

        # Create a dict of all previously processed product IDs for fast lookup.
        existing_products = {}
        products_query = models.AppleSUSProduct.all()
        for product in products_query:
            existing_products[product.product_id] = True

        # Loop over all products IDs in the Apple Updates catalog, adding any new
        # products to the models.AppleSUSProduct model.
        catalog_product_keys = catalog_plist.get('Products', {}).keys()
        catalog_product_keys.sort()
        for key in catalog_product_keys:
            if key in existing_products:
                continue  # This product has already been processed in the past.

            #logging.debug('Processing new product: %s', key)

            distributions = catalog_plist['Products'][key]['Distributions']
            url = distributions.get('English', None) or distributions.get(
                'en', None)
            if not url:
                logging.error(
                    'No english distributions exists for product %s; skipping.',
                    key)
                continue  # No english distribution exists :(

            r = urllib2.urlopen(url)
            if r.code != 200:
                #logging.warning('Skipping dist where HTTP status != 200')
                continue
            dist_str = r.read()
            dist = applesus.DistFileDocument()
            dist.LoadDocument(dist_str)

            product = models.AppleSUSProduct(key_name=key)
            product.product_id = key
            product.name = dist.title
            product.apple_mtime = catalog_plist['Products'][key]['PostDate']
            product.version = dist.version
            product.description = dist.description
            product.tracks = [common.UNSTABLE]
            product.restart_required = dist.restart_required
            if not dist.restart_required and settings.APPLE_AUTO_UNATTENDED_ENABLED:
                product.unattended = True
            else:
                product.unattended = False
            product.put()
            new_products.append(product)

            #logging.debug('Product complete: %s', product.name)

        return new_products