def testDeleteCompanies(self, deleteMetricMock, getAllCustomMetricsMock,
                            getAllMetricSecuritiesMock,
                            _flushTaurusEngineMetricDataPathMock,
                            engineFactoryMock):
        negatives = set([
            "TWITTER.TWEET.HANDLE.ZZZ.VOLUME",
            "XIGNITE.ZZZ.CLOSINGPRICE",
            "XIGNITE.FOOBARZZZ.CLOSINGPRICE",
            "XIGNITE.ZZZFOOBAR.CLOSINGPRICE",
            "XIGNITE.FOOBAR.ZZZ.VOLUME",
            "XIGNITE.NEWS.FOOBAR.ZZZ.VOLUME",
            "FOOBAR.VOLUME",
            ".FOOBAR.CLOSINGPRICE",
            "XIGNITE.FOOBAR.",
            "FOOBARCLOSINGPRICE",
        ])

        positives = set([
            "XIGNITE.FOOBAR.CLOSINGPRICE",
            "XIGNITE.FOOBAR.VOLUME",
            "TWITTER.TWEET.HANDLE.FOOBAR.VOLUME",
            "XIGNITE.NEWS.FOOBAR.VOLUME",
            "XIGNITE.DOLITTLE.VOLUME",
        ])

        # Patch getAllCustomMetrics to return all negatives and positives
        getAllCustomMetricsMock.return_value = [{
            "uid": uuid.uuid1().hex,
            "name": metric
        } for metric in negatives.union(positives)]

        # Simulate xitgnite_security found for first symbol, but not the second one.
        engineFactoryMock.return_value.begin.return_value.__enter__.return_value \
          .execute.side_effect = [Mock(rowcount=1), Mock(rowcount=0)]

        getAllMetricSecuritiesMock.return_value = [("IBM", "exg"),
                                                   ("T", "exg")]

        # Execute the function under test
        delete_companies.deleteCompanies(tickerSymbols=("FOOBAR", "DOLITTLE"),
                                         engineServer="host",
                                         engineApiKey="apikey",
                                         warnAboutDestructiveAction=False)

        # Verify that deleteMetric was called only on the positives
        expectedDeleteMetricCalls = [
            mock.call(host="host", apiKey="apikey", metricName=metric)
            for metric in positives
        ]

        self.maxDiff = None
        self.assertItemsEqual(deleteMetricMock.call_args_list,
                              expectedDeleteMetricCalls)

        self.assertEqual(
            engineFactoryMock.return_value.begin.return_value.__enter__.
            return_value.execute.call_count, 2)
  def testDeleteCompaniesWithWarningConfirmation(
      self,
      deleteMetricMock,
      getAllCustomMetricsMock,
      getAllMetricSecuritiesMock,
      warnAboutDestructiveActionMock,
      _flushTaurusEngineMetricDataPathMock,
      engineFactoryMock):

    negatives = set([
      "TWITTER.TWEET.HANDLE.ZZZ.VOLUME",
    ])

    positives = set([
      "XIGNITE.FOOBAR.CLOSINGPRICE",
    ])

    # Patch getAllCustomMetrics to return all negatives and positives
    getAllCustomMetricsMock.return_value = [
      {"uid": uuid.uuid1().hex, "name": metric}
      for metric in negatives.union(positives)
    ]

    engineFactoryMock.return_value.begin.return_value.__enter__.return_value \
      .execute.return_value.rowcount = 1

    getAllMetricSecuritiesMock.return_value = [
      ("IBM", "exg"),
      ("T", "exg")
    ]

    # Execute the function under test with default warnAboutDestructiveAction
    delete_companies.deleteCompanies(
      tickerSymbols=("FOOBAR", "DOLITTLE"),
      engineServer="host",
      engineApiKey="apikey")

    # Verify that _warnAboutDestructiveAction was called
    self.assertEqual(warnAboutDestructiveActionMock.call_count, 1)

    # Verify that deleteMetric was called only on the positives
    expectedDeleteMetricCalls = [
      mock.call(host="host", apiKey="apikey", metricName=metric)
      for metric in positives
    ]

    self.maxDiff = None
    self.assertItemsEqual(deleteMetricMock.call_args_list,
                          expectedDeleteMetricCalls)

    self.assertEqual(engineFactoryMock.return_value.begin.return_value
                     .__enter__.return_value.execute.call_count, 1)
    def testDeleteCompaniesWithWarningTimeout(self,
                                              warnAboutDestructiveActionMock):

        warnAboutDestructiveActionMock.side_effect = (
            delete_companies.WarningPromptTimeout)

        # Execute the function under test with default warnAboutDestructiveAction
        with self.assertRaises(delete_companies.WarningPromptTimeout):
            delete_companies.deleteCompanies(tickerSymbols=("FOOBAR",
                                                            "DOLITTLE"),
                                             engineServer="host",
                                             engineApiKey="apikey")

        # Verify that _warnAboutDestructiveAction was called
        self.assertEqual(warnAboutDestructiveActionMock.call_count, 1)
  def testDeleteCompaniesWithWarningTimeout(self,
                                            warnAboutDestructiveActionMock):

    warnAboutDestructiveActionMock.side_effect = (
      delete_companies.WarningPromptTimeout)

    # Execute the function under test with default warnAboutDestructiveAction
    with self.assertRaises(delete_companies.WarningPromptTimeout):
      delete_companies.deleteCompanies(
        tickerSymbols=("FOOBAR", "DOLITTLE"),
        engineServer="host",
        engineApiKey="apikey")

    # Verify that _warnAboutDestructiveAction was called
    self.assertEqual(warnAboutDestructiveActionMock.call_count, 1)
    def testDeleteCompaniesWithWarningConfirmation(
            self, deleteMetricMock, getAllCustomMetricsMock,
            getAllMetricSecuritiesMock, warnAboutDestructiveActionMock,
            _flushTaurusEngineMetricDataPathMock, engineFactoryMock):

        negatives = set([
            "TWITTER.TWEET.HANDLE.ZZZ.VOLUME",
        ])

        positives = set([
            "XIGNITE.FOOBAR.CLOSINGPRICE",
        ])

        # Patch getAllCustomMetrics to return all negatives and positives
        getAllCustomMetricsMock.return_value = [{
            "uid": uuid.uuid1().hex,
            "name": metric
        } for metric in negatives.union(positives)]

        engineFactoryMock.return_value.begin.return_value.__enter__.return_value \
          .execute.return_value.rowcount = 1

        getAllMetricSecuritiesMock.return_value = [("IBM", "exg"),
                                                   ("T", "exg")]

        # Execute the function under test with default warnAboutDestructiveAction
        delete_companies.deleteCompanies(tickerSymbols=("FOOBAR", "DOLITTLE"),
                                         engineServer="host",
                                         engineApiKey="apikey")

        # Verify that _warnAboutDestructiveAction was called
        self.assertEqual(warnAboutDestructiveActionMock.call_count, 1)

        # Verify that deleteMetric was called only on the positives
        expectedDeleteMetricCalls = [
            mock.call(host="host", apiKey="apikey", metricName=metric)
            for metric in positives
        ]

        self.maxDiff = None
        self.assertItemsEqual(deleteMetricMock.call_args_list,
                              expectedDeleteMetricCalls)

        self.assertEqual(
            engineFactoryMock.return_value.begin.return_value.__enter__.
            return_value.execute.call_count, 1)
Ejemplo n.º 6
0
def _purgeDeprecatedCompanies():
  """Purge cached data and Taurus Engine metrics/models corresponding to symbols
  that are in xignite_security table, but not in metrics configuration.
  """
  activeCompanySymbols = set(security[0] for security in
                             metric_utils.getAllMetricSecurities())

  deprecatedSymbols = set(_queryCachedCompanySymbols()) - activeCompanySymbols

  if deprecatedSymbols:
    delete_companies.deleteCompanies(
      tickerSymbols=deprecatedSymbols,
      engineServer=_TAURUS_HTM_SERVER,
      engineApiKey=_TAURUS_API_KEY,
      warnAboutDestructiveAction=False)
  else:
    g_log.info("There were no deprecated companies to remove")
  def testDeleteCompanies(self):
    host = os.environ.get("TAURUS_HTM_SERVER", "127.0.0.1")
    apiKey = os.environ.get("TAURUS_APIKEY", "taurus")

    # We have four target stocker ticker symbols here:
    #  FOOBAR: has both metrics and an xignite_security symbol
    #  DOLITTLE: has metrics, but no xignite_security symbol
    #  KNOWLITTLE: has no metrics, but has an xignite_security symbol
    #  GOTNOTHING: has neither metrics, nor xignite_security symbol

    negatives = set([
      "{uuid}.ZZZZZZ.CLOSINGPRICE".format(uuid=uuid.uuid1().hex),
      "{uuid}.FOOBAR.ZZZZZZ.VOLUME".format(uuid=uuid.uuid1().hex),
      "FOOBAR.{uuid}".format(uuid=uuid.uuid1().hex),
      ".FOOBAR.{uuid}".format(uuid=uuid.uuid1().hex),
      "{uuid}.FOOBAR.".format(uuid=uuid.uuid1().hex),
      "{uuid}FOOBARCLOSINGPRICE".format(uuid=uuid.uuid1().hex),
    ])

    positives = set([
      "{uuid}.FOOBAR.CLOSINGPRICE".format(uuid=uuid.uuid1().hex),
      "{uuid}.FOOBAR.VOLUME".format(uuid=uuid.uuid1().hex),
      "{uuid}.TWEET.HANDLE.FOOBAR.VOLUME".format(uuid=uuid.uuid1().hex),
      "{uuid}.NEWS.FOOBAR.VOLUME".format(uuid=uuid.uuid1().hex),
      "{uuid}.DOLITTLE.CLOSINGPRICE".format(uuid=uuid.uuid1().hex),
      "{uuid}.DOLITTLE.VOLUME".format(uuid=uuid.uuid1().hex),
      "{uuid}.TWEET.HANDLE.DOLITTLE.VOLUME".format(uuid=uuid.uuid1().hex),
    ])

    allTestMetricNames = negatives.union(positives)

    # Register cleanup actions
    for metric in allTestMetricNames:
      self.addCleanup(_safeDeleteMetric,
                      host=host,
                      apiKey=apiKey,
                      metricName=metric)

    # Create custom models. They will be created in "pending data"" state, since
    # we're providing neither data nor min/max; thus we don't need to wait for
    # them to enter "active" model state
    for metric in allTestMetricNames:
      metric_utils.createCustomHtmModel(host=host,
                                        apiKey=apiKey,
                                        metricName=metric,
                                        resourceName=metric,
                                        userInfo=dict(),
                                        modelParams=dict())

    # Verify that all metrics got created in Taurus Engine now
    remoteMetricNames = set(obj["name"] for obj in
                            metric_utils.getAllModels(host, apiKey))
    self.assertTrue(allTestMetricNames.issubset(remoteMetricNames),
                    "Some models didn't get created: {metrics}".format(
                      metrics=allTestMetricNames.difference(remoteMetricNames)))

    # Add FOOBAR and KNOWLITTLE to xignite_security table
    def securityExists(symbol):
      security = collectorsdb.engineFactory().execute(
        sql.select([schema.xigniteSecurity.c.symbol])
        .where(schema.xigniteSecurity.c.symbol == symbol)
      ).scalar()

      if security is not None:
        self.assertEqual(security, symbol)
        return True

      return False

    def addSecurity(symbol):
      self.addCleanup(_deleteSecurity, symbol)
      xignite_agent_utils.insertSecurity(
        engine=collectorsdb.engineFactory(),
        xigniteSecurity={
          "Symbol": symbol,
          "CIK": "CIK",
          "CUSIP": "CUSIP",
          "ISIN": "ISIN",
          "Valoren": "Valoren",
          "Name": "{sym} Inc.".format(sym=symbol),
          "Market": "Market",
          "MarketIdentificationCode": "mic1",
          "MostLiquidExchange": True,
          "CategoryOrIndustry": "CategoryOrIndustry"
        })

      self.assertTrue(securityExists(symbol),
                      "inserted {symbol} not found".format(symbol=symbol))


    addSecurity("FOOBAR")
    addSecurity("KNOWLITTLE")

    # Delete companies corresponding to our target ticker symbols
    delete_companies.deleteCompanies(
      tickerSymbols=["FOOBAR", "DOLITTLE", "KNOWLITTLE", "GOTNOTHING"],
      engineServer=host,
      engineApiKey=apiKey,
      warnAboutDestructiveAction=False)

    # Verify that positives got deleted and negatives didn't
    remoteMetricNames = set(obj["name"] for obj in
                            metric_utils.getAllModels(host, apiKey))
    self.assertTrue(positives.isdisjoint(remoteMetricNames),
                    "Some positives didn't get deleted: {metrics}".format(
                      metrics=positives.intersection(remoteMetricNames)))

    self.assertTrue(negatives.issubset(remoteMetricNames),
                    "Some negatives got deleted: {metrics}".format(
                      metrics=negatives.difference(remoteMetricNames)))

    # Verify that FOOBAR and KNOWLITTLE got deleted from xignite_security table
    self.assertFalse(securityExists("FOOBAR"),
                     "FOOBAR not deleted from xignite_security")
    self.assertFalse(securityExists("FOOBAR"),
                     "KNOWLITTLE not deleted from xignite_security")
  def testDeleteCompanies(self,
                          deleteMetricMock,
                          getAllCustomMetricsMock,
                          getAllMetricSecuritiesMock,
                          _flushTaurusEngineMetricDataPathMock,
                          engineFactoryMock):
    negatives = set([
      "TWITTER.TWEET.HANDLE.ZZZ.VOLUME",
      "XIGNITE.ZZZ.CLOSINGPRICE",
      "XIGNITE.FOOBARZZZ.CLOSINGPRICE",
      "XIGNITE.ZZZFOOBAR.CLOSINGPRICE",
      "XIGNITE.FOOBAR.ZZZ.VOLUME",
      "XIGNITE.NEWS.FOOBAR.ZZZ.VOLUME",
      "FOOBAR.VOLUME",
      ".FOOBAR.CLOSINGPRICE",
      "XIGNITE.FOOBAR.",
      "FOOBARCLOSINGPRICE",
    ])

    positives = set([
      "XIGNITE.FOOBAR.CLOSINGPRICE",
      "XIGNITE.FOOBAR.VOLUME",
      "TWITTER.TWEET.HANDLE.FOOBAR.VOLUME",
      "XIGNITE.NEWS.FOOBAR.VOLUME",
      "XIGNITE.DOLITTLE.VOLUME",
    ])

    # Patch getAllCustomMetrics to return all negatives and positives
    getAllCustomMetricsMock.return_value = [
      {"uid": uuid.uuid1().hex, "name": metric}
      for metric in negatives.union(positives)
    ]

    # Simulate xitgnite_security found for first symbol, but not the second one.
    engineFactoryMock.return_value.begin.return_value.__enter__.return_value \
      .execute.side_effect = [Mock(rowcount=1), Mock(rowcount=0)]

    getAllMetricSecuritiesMock.return_value = [
      ("IBM", "exg"),
      ("T", "exg")
    ]

    # Execute the function under test
    delete_companies.deleteCompanies(
      tickerSymbols=("FOOBAR", "DOLITTLE"),
      engineServer="host",
      engineApiKey="apikey",
      warnAboutDestructiveAction=False)

    # Verify that deleteMetric was called only on the positives
    expectedDeleteMetricCalls = [
      mock.call(host="host", apiKey="apikey", metricName=metric)
      for metric in positives
    ]

    self.maxDiff = None
    self.assertItemsEqual(deleteMetricMock.call_args_list,
                          expectedDeleteMetricCalls)

    self.assertEqual(engineFactoryMock.return_value.begin.return_value
                     .__enter__.return_value.execute.call_count, 2)