<commit_before>/*
*
* Copyright 2013 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* iot_support at tid dot es
*
* Author: Ken Zangelin
*/
#include <string>
#include <vector>

#include "logMsg/logMsg.h"
#include "logMsg/traceLevels.h"

#include "common/string.h"
#include "common/globals.h"
#include "common/tag.h"
#include "common/statistics.h"
#include "common/sem.h"

#include "ngsi/ParseData.h"
#include "rest/ConnectionInfo.h"
#include "rest/rest.h"
#include "serviceRoutines/statisticsTreat.h"
#include "mongoBackend/mongoConnectionPool.h"
#include "cache/subCache.h"

#include "ngsiNotify/QueueStatistics.h"

#include "common/JsonHelper.h"

/* ****************************************************************************
*
* TAG_ADD -
*/
#define TAG_ADD_COUNTER(tag, counter) valueTag(indent2, tag, counter + 1, ciP->outFormat, true)
#define TAG_ADD_STRING(tag, value)  valueTag(indent2, tag, value, ciP->outFormat, true)
#define TAG_ADD_INTEGER(tag, value, comma)  valueTag(indent2, tag, value, ciP->outFormat, comma)

static void resetStatistics(void)
{
  noOfJsonRequests                                = -1;
  noOfXmlRequests                                 = -1;
  noOfRegistrations                               = -1;
  noOfRegistrationErrors                          = -1;
  noOfRegistrationUpdates                         = -1;
  noOfRegistrationUpdateErrors                    = -1;
  noOfDiscoveries                                 = -1;
  noOfDiscoveryErrors                             = -1;
  noOfAvailabilitySubscriptions                   = -1;
  noOfAvailabilitySubscriptionErrors              = -1;
  noOfAvailabilityUnsubscriptions                 = -1;
  noOfAvailabilityUnsubscriptionErrors            = -1;
  noOfAvailabilitySubscriptionUpdates             = -1;
  noOfAvailabilitySubscriptionUpdateErrors        = -1;
  noOfAvailabilityNotificationsReceived           = -1;
  noOfAvailabilityNotificationsSent               = -1;

  noOfQueries                                     = -1;
  noOfQueryErrors                                 = -1;
  noOfUpdates                                     = -1;
  noOfUpdateErrors                                = -1;
  noOfSubscriptions                               = -1;
  noOfSubscriptionErrors                          = -1;
  noOfSubscriptionUpdates                         = -1;
  noOfSubscriptionUpdateErrors                    = -1;
  noOfUnsubscriptions                             = -1;
  noOfUnsubscriptionErrors                        = -1;
  noOfNotificationsReceived                       = -1;
  noOfNotificationsSent                           = -1;
  noOfQueryContextResponses                       = -1;
  noOfUpdateContextResponses                      = -1;

  noOfContextEntitiesByEntityId                   = -1;
  noOfContextEntityAttributes                     = -1;
  noOfEntityByIdAttributeByName                   = -1;
  noOfContextEntityTypes                          = -1;
  noOfContextEntityTypeAttributeContainer         = -1;
  noOfContextEntityTypeAttribute                  = -1;

  noOfIndividualContextEntity                     = -1;
  noOfIndividualContextEntityAttributes           = -1;
  noOfIndividualContextEntityAttribute            = -1;
  noOfUpdateContextElement                        = -1;
  noOfAppendContextElement                        = -1;
  noOfUpdateContextAttribute                      = -1;

  noOfNgsi10ContextEntityTypes                    = -1;
  noOfNgsi10ContextEntityTypesAttributeContainer  = -1;
  noOfNgsi10ContextEntityTypesAttribute           = -1;
  noOfNgsi10SubscriptionsConvOp                   = -1;

  noOfAllContextEntitiesRequests                    = -1;
  noOfAllEntitiesWithTypeAndIdRequests              = -1;
  noOfIndividualContextEntityAttributeWithTypeAndId = -1;
  noOfAttributeValueInstanceWithTypeAndId           = -1;
  noOfContextEntitiesByEntityIdAndType              = -1;
  noOfEntityByIdAttributeByNameIdAndType            = -1;

  noOfLogRequests                                 = -1;
  noOfVersionRequests                             = -1;
  noOfExitRequests                                = -1;
  noOfLeakRequests                                = -1;
  noOfStatisticsRequests                          = -1;
  noOfInvalidRequests                             = -1;
  noOfRegisterResponses                           = -1;

  noOfSimulatedNotifications                      = -1;

  QueueStatistics::reset();

  semTimeReqReset();
  semTimeTransReset();
  semTimeCacheReset();
  semTimeTimeStatReset();
  mongoPoolConnectionSemWaitingTimeReset();
  mutexTimeCCReset();

  timingStatisticsReset();
}

/* ****************************************************************************
*
*  - addUserCounter
*/
inline void renderUsedCounter(JsonHelper* js, const std::string& field, int counter)
{
  if (counter != -1)
  {
    js->addNumber(field, counter + 1);
  }
}

/* ****************************************************************************
*
*  - renderCounterStats
*/
std::string renderCounterStats(void)
{
  JsonHelper js;

  // FIXME: try to chose names closer to the ones used in API URLs
  renderUsedCounter(&js, "xmlRequests",                               noOfXmlRequests);
  renderUsedCounter(&js, "jsonRequests",                              noOfJsonRequests);
  renderUsedCounter(&js, "registrations",                             noOfRegistrations);
  renderUsedCounter(&js, "registrationUpdates",                       noOfRegistrationUpdates);
  renderUsedCounter(&js, "discoveries",                               noOfDiscoveries);
  renderUsedCounter(&js, "availabilitySubscriptions",                 noOfAvailabilitySubscriptions);
  renderUsedCounter(&js, "availabilitySubscriptionUpdates",           noOfAvailabilitySubscriptionUpdates);
  renderUsedCounter(&js, "availabilityUnsubscriptions",               noOfAvailabilityUnsubscriptions);
  renderUsedCounter(&js, "availabilityNotificationsReceived",         noOfAvailabilityNotificationsReceived);
  renderUsedCounter(&js, "availabilityNotificationsSent",             noOfAvailabilityNotificationsSent);
  renderUsedCounter(&js, "queries",                                   noOfQueries);
  renderUsedCounter(&js, "updates",                                   noOfUpdates);
  renderUsedCounter(&js, "subscriptions",                             noOfSubscriptions);
  renderUsedCounter(&js, "subscriptionUpdates",                       noOfSubscriptionUpdates);
  renderUsedCounter(&js, "unsubscriptions",                           noOfUnsubscriptions);
  renderUsedCounter(&js, "notificationsReceived",                     noOfNotificationsReceived);
  renderUsedCounter(&js, "notificationsSent",                         noOfNotificationsSent);
  renderUsedCounter(&js, "queryResponsesReceived",                    noOfQueryContextResponses);
  renderUsedCounter(&js, "updateResponsesReceived",                   noOfUpdateContextResponses);
  renderUsedCounter(&js, "contextEntitiesByEntityId",                 noOfContextEntitiesByEntityId);
  renderUsedCounter(&js, "contextEntityAttributes",                   noOfContextEntityAttributes);
  renderUsedCounter(&js, "entityByIdAttributeByName",                 noOfEntityByIdAttributeByName);
  renderUsedCounter(&js, "ctxEntityTypes",                            noOfContextEntityTypes);
  renderUsedCounter(&js, "ctxEntityTypeAttributeContainer",           noOfContextEntityTypeAttributeContainer);
  renderUsedCounter(&js, "ctxEntityTypeAttribute",                    noOfContextEntityTypeAttribute);
  renderUsedCounter(&js, "individualContextEntity",                   noOfIndividualContextEntity);
  renderUsedCounter(&js, "individualContextEntityAttributes",         noOfIndividualContextEntityAttributes);
  renderUsedCounter(&js, "individualContextEntityAttribute",          noOfIndividualContextEntityAttribute);
  renderUsedCounter(&js, "updateContextElement",                      noOfUpdateContextElement);
  renderUsedCounter(&js, "appendContextElement",                      noOfAppendContextElement);
  renderUsedCounter(&js, "updateContextAttribute",                    noOfUpdateContextAttribute);
  renderUsedCounter(&js, "ctxEntityTypesNgsi10",                      noOfNgsi10ContextEntityTypes);
  renderUsedCounter(&js, "ctxEntityTypeAttributeContainerNgsi10",     noOfNgsi10ContextEntityTypesAttributeContainer);
  renderUsedCounter(&js, "ctxEntityTypeAttributeNgsi10",              noOfNgsi10ContextEntityTypesAttribute);
  renderUsedCounter(&js, "subscriptionsNgsi10ConvOp",                 noOfNgsi10SubscriptionsConvOp);
  renderUsedCounter(&js, "allContextEntitiesRequests",                noOfAllContextEntitiesRequests);
  renderUsedCounter(&js, "allEntitiesWithTypeAndIdRequests",          noOfAllEntitiesWithTypeAndIdRequests);
  renderUsedCounter(&js, "individualCtxEntityAttributeWithTypeAndId", noOfIndividualContextEntityAttributeWithTypeAndId);
  renderUsedCounter(&js, "attributeValueInstanceWithTypeAndId",       noOfAttributeValueInstanceWithTypeAndId);
  renderUsedCounter(&js, "contextEntitiesByEntityIdAndType",          noOfContextEntitiesByEntityIdAndType);
  renderUsedCounter(&js, "entityByIdAttributeByNameIdAndType",        noOfEntityByIdAttributeByNameIdAndType);
  renderUsedCounter(&js, "logRequests", noOfLogRequests);

  //
  // The valgrind test suite uses REST GET /version to check that the broker is alive
  // This fact makes the statistics change and some working functests fail under valgrindTestSuite
  // due to the 'extra' version-request in the statistics.
  // Instead of removing version-requests from the statistics,
  // we report the number of version-requests even if zero (-1).
  //
  js.addNumber("versionRequests", noOfVersionRequests + 1);

  renderUsedCounter(&js, "exitRequests", noOfExitRequests);
  renderUsedCounter(&js, "leakRequests", noOfLeakRequests);
  renderUsedCounter(&js, "statisticsRequests", noOfStatisticsRequests);
  renderUsedCounter(&js, "invalidRequests", noOfInvalidRequests);
  renderUsedCounter(&js, "registerResponses", noOfRegisterResponses);
  renderUsedCounter(&js, "registrationErrors", noOfRegistrationErrors);
  renderUsedCounter(&js, "registrationUpdateErrors", noOfRegistrationUpdateErrors);
  renderUsedCounter(&js, "discoveryErrors", noOfDiscoveryErrors);

  return js.str();
}

/* ****************************************************************************
*
*  - renderSemWaitStats
*/
std::string renderSemWaitStats(void)
{
  JsonHelper jh;

  jh.addFloat("request",           semTimeReqGet());
  jh.addFloat("dbConnectionPool",  mongoPoolConnectionSemWaitingTimeGet());
  jh.addFloat("transaction",       semTimeTransGet());
  jh.addFloat("subCache",          semTimeCacheGet());
  jh.addFloat("connectionContext", mutexTimeCCGet());
  jh.addFloat("timeStat",          semTimeTimeStatGet());

  return jh.str();
}

/* ****************************************************************************
*
*  - renderNotifQueueStats
*/
std::string renderNotifQueueStats(void)
{
  JsonHelper jh;
  float      timeInQ = QueueStatistics::getTimeInQ();
  int        out     = QueueStatistics::getOut();

  jh.addNumber("in",             QueueStatistics::getIn());
  jh.addNumber("out",            out);
  jh.addNumber("reject",         QueueStatistics::getReject());
  jh.addNumber("sentOk",         QueueStatistics::getSentOK());     // FIXME P7: this needs to be generalized for all notificationModes
  jh.addNumber("sentError",      QueueStatistics::getSentError());  // FIXME P7: this needs to be generalized for all notificationModes
  jh.addFloat ("timeInQueue",    timeInQ);
  jh.addFloat ("avgTimeInQueue", (timeInQ/out));
  jh.addNumber("size",           QueueStatistics::getQSize());

  return jh.str();
}

/* ****************************************************************************
*
* xmlUseError -
*/
static std::string xmlUseError(void)
{
  std::string out = "";

  out += startTag("", "orion", "", XML, false, false, false);
  out += valueTag("  ", "message", "XML not supported in statistics operations, use JSON", XML);
  out += endTag("", "orion", XML, false, false, true, false);

  return out;
}

/* ****************************************************************************
*
* statisticsTreat -
*/
std::string statisticsTreat
(
  ConnectionInfo*            ciP,
  int                        components,
  std::vector<std::string>&  compV,
  ParseData*                 parseDataP
)
{
  if (ciP->outFormat == XML)
  {
    return xmlUseError();
  }

  JsonHelper js;

  if (ciP->method == "DELETE")
  {
    resetStatistics();
    js.addString("message", "All statistics counter reset");
    return js.str();
  }

  /* Conditional statistics (in the same order as described in statistics.md, although
   * beautifier tools may change this order */
  if (countersStatistics)
  {
    js.addRaw("counters", renderCounterStats());
  }
  if (semWaitStatistics)
  {
    js.addRaw("semWait", renderSemWaitStats());
  }
  if (timingStatistics)
  {
    js.addRaw("timing", renderTimingStatistics());
  }
  if ((notifQueueStatistics) && (strcmp(notificationMode, "threadpool") == 0))
  {
    js.addRaw("notifQueue", renderNotifQueueStats());
  }

  // Unconditional stats
  int now = getCurrentTime();
  js.addNumber("uptime_in_secs", now - startTime);
  js.addNumber("measuring_interval_in_secs", now - statisticsTime);

  // Special case: simulated notifications
  int nSimNotif = __sync_fetch_and_add(&noOfSimulatedNotifications, 0);
  renderUsedCounter(&js, "simulatedNotifications", nSimNotif);

  ciP->httpStatusCode = SccOk;
  return js.str();

}

/* ****************************************************************************
*
* statisticsCacheTreat -
*
*/
std::string statisticsCacheTreat
(
  ConnectionInfo*            ciP,
  int                        components,
  std::vector<std::string>&  compV,
  ParseData*                 parseDataP
)
{
  if (ciP->outFormat == XML)
  {
    return xmlUseError();
  }

  JsonHelper js;

  if (ciP->method == "DELETE")
  {
    subCacheStatisticsReset("statisticsTreat::DELETE");
    js.addString("message", "All statistics counter reset");
    return js.str();
  }

  //
  // mongo sub cache counters
  //
  int   mscRefreshs = 0;
  int   mscInserts  = 0;
  int   mscRemoves  = 0;
  int   mscUpdates  = 0;
  int   cacheItems  = 0;
  char  listBuffer[1024];

  cacheSemTake(__FUNCTION__, "statisticsCacheTreat");
  subCacheStatisticsGet(&mscRefreshs, &mscInserts, &mscRemoves, &mscUpdates, &cacheItems, listBuffer, sizeof(listBuffer));
  cacheSemGive(__FUNCTION__, "statisticsCacheTreat");

  js.addString("ids", listBuffer);    // FIXME P10: this seems not printing anything... is listBuffer working fine?
  js.addNumber("refresh", mscRefreshs);
  js.addNumber("inserts", mscInserts);
  js.addNumber("removes", mscRemoves);
  js.addNumber("updates", mscUpdates);
  js.addNumber("items", cacheItems);

  ciP->httpStatusCode = SccOk;
  return js.str();
}
<commit_msg>average time in q when out is zero<commit_after>/*
*
* Copyright 2013 Telefonica Investigacion y Desarrollo, S.A.U
*
* This file is part of Orion Context Broker.
*
* Orion Context Broker is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Orion Context Broker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Orion Context Broker. If not, see http://www.gnu.org/licenses/.
*
* For those usages not covered by this license please contact with
* iot_support at tid dot es
*
* Author: Ken Zangelin
*/
#include <string>
#include <vector>

#include "logMsg/logMsg.h"
#include "logMsg/traceLevels.h"

#include "common/string.h"
#include "common/globals.h"
#include "common/tag.h"
#include "common/statistics.h"
#include "common/sem.h"

#include "ngsi/ParseData.h"
#include "rest/ConnectionInfo.h"
#include "rest/rest.h"
#include "serviceRoutines/statisticsTreat.h"
#include "mongoBackend/mongoConnectionPool.h"
#include "cache/subCache.h"

#include "ngsiNotify/QueueStatistics.h"

#include "common/JsonHelper.h"

/* ****************************************************************************
*
* TAG_ADD -
*/
#define TAG_ADD_COUNTER(tag, counter) valueTag(indent2, tag, counter + 1, ciP->outFormat, true)
#define TAG_ADD_STRING(tag, value)  valueTag(indent2, tag, value, ciP->outFormat, true)
#define TAG_ADD_INTEGER(tag, value, comma)  valueTag(indent2, tag, value, ciP->outFormat, comma)

static void resetStatistics(void)
{
  noOfJsonRequests                                = -1;
  noOfXmlRequests                                 = -1;
  noOfRegistrations                               = -1;
  noOfRegistrationErrors                          = -1;
  noOfRegistrationUpdates                         = -1;
  noOfRegistrationUpdateErrors                    = -1;
  noOfDiscoveries                                 = -1;
  noOfDiscoveryErrors                             = -1;
  noOfAvailabilitySubscriptions                   = -1;
  noOfAvailabilitySubscriptionErrors              = -1;
  noOfAvailabilityUnsubscriptions                 = -1;
  noOfAvailabilityUnsubscriptionErrors            = -1;
  noOfAvailabilitySubscriptionUpdates             = -1;
  noOfAvailabilitySubscriptionUpdateErrors        = -1;
  noOfAvailabilityNotificationsReceived           = -1;
  noOfAvailabilityNotificationsSent               = -1;

  noOfQueries                                     = -1;
  noOfQueryErrors                                 = -1;
  noOfUpdates                                     = -1;
  noOfUpdateErrors                                = -1;
  noOfSubscriptions                               = -1;
  noOfSubscriptionErrors                          = -1;
  noOfSubscriptionUpdates                         = -1;
  noOfSubscriptionUpdateErrors                    = -1;
  noOfUnsubscriptions                             = -1;
  noOfUnsubscriptionErrors                        = -1;
  noOfNotificationsReceived                       = -1;
  noOfNotificationsSent                           = -1;
  noOfQueryContextResponses                       = -1;
  noOfUpdateContextResponses                      = -1;

  noOfContextEntitiesByEntityId                   = -1;
  noOfContextEntityAttributes                     = -1;
  noOfEntityByIdAttributeByName                   = -1;
  noOfContextEntityTypes                          = -1;
  noOfContextEntityTypeAttributeContainer         = -1;
  noOfContextEntityTypeAttribute                  = -1;

  noOfIndividualContextEntity                     = -1;
  noOfIndividualContextEntityAttributes           = -1;
  noOfIndividualContextEntityAttribute            = -1;
  noOfUpdateContextElement                        = -1;
  noOfAppendContextElement                        = -1;
  noOfUpdateContextAttribute                      = -1;

  noOfNgsi10ContextEntityTypes                    = -1;
  noOfNgsi10ContextEntityTypesAttributeContainer  = -1;
  noOfNgsi10ContextEntityTypesAttribute           = -1;
  noOfNgsi10SubscriptionsConvOp                   = -1;

  noOfAllContextEntitiesRequests                    = -1;
  noOfAllEntitiesWithTypeAndIdRequests              = -1;
  noOfIndividualContextEntityAttributeWithTypeAndId = -1;
  noOfAttributeValueInstanceWithTypeAndId           = -1;
  noOfContextEntitiesByEntityIdAndType              = -1;
  noOfEntityByIdAttributeByNameIdAndType            = -1;

  noOfLogRequests                                 = -1;
  noOfVersionRequests                             = -1;
  noOfExitRequests                                = -1;
  noOfLeakRequests                                = -1;
  noOfStatisticsRequests                          = -1;
  noOfInvalidRequests                             = -1;
  noOfRegisterResponses                           = -1;

  noOfSimulatedNotifications                      = -1;

  QueueStatistics::reset();

  semTimeReqReset();
  semTimeTransReset();
  semTimeCacheReset();
  semTimeTimeStatReset();
  mongoPoolConnectionSemWaitingTimeReset();
  mutexTimeCCReset();

  timingStatisticsReset();
}

/* ****************************************************************************
*
*  - addUserCounter
*/
inline void renderUsedCounter(JsonHelper* js, const std::string& field, int counter)
{
  if (counter != -1)
  {
    js->addNumber(field, counter + 1);
  }
}

/* ****************************************************************************
*
*  - renderCounterStats
*/
std::string renderCounterStats(void)
{
  JsonHelper js;

  // FIXME: try to chose names closer to the ones used in API URLs
  renderUsedCounter(&js, "xmlRequests",                               noOfXmlRequests);
  renderUsedCounter(&js, "jsonRequests",                              noOfJsonRequests);
  renderUsedCounter(&js, "registrations",                             noOfRegistrations);
  renderUsedCounter(&js, "registrationUpdates",                       noOfRegistrationUpdates);
  renderUsedCounter(&js, "discoveries",                               noOfDiscoveries);
  renderUsedCounter(&js, "availabilitySubscriptions",                 noOfAvailabilitySubscriptions);
  renderUsedCounter(&js, "availabilitySubscriptionUpdates",           noOfAvailabilitySubscriptionUpdates);
  renderUsedCounter(&js, "availabilityUnsubscriptions",               noOfAvailabilityUnsubscriptions);
  renderUsedCounter(&js, "availabilityNotificationsReceived",         noOfAvailabilityNotificationsReceived);
  renderUsedCounter(&js, "availabilityNotificationsSent",             noOfAvailabilityNotificationsSent);
  renderUsedCounter(&js, "queries",                                   noOfQueries);
  renderUsedCounter(&js, "updates",                                   noOfUpdates);
  renderUsedCounter(&js, "subscriptions",                             noOfSubscriptions);
  renderUsedCounter(&js, "subscriptionUpdates",                       noOfSubscriptionUpdates);
  renderUsedCounter(&js, "unsubscriptions",                           noOfUnsubscriptions);
  renderUsedCounter(&js, "notificationsReceived",                     noOfNotificationsReceived);
  renderUsedCounter(&js, "notificationsSent",                         noOfNotificationsSent);
  renderUsedCounter(&js, "queryResponsesReceived",                    noOfQueryContextResponses);
  renderUsedCounter(&js, "updateResponsesReceived",                   noOfUpdateContextResponses);
  renderUsedCounter(&js, "contextEntitiesByEntityId",                 noOfContextEntitiesByEntityId);
  renderUsedCounter(&js, "contextEntityAttributes",                   noOfContextEntityAttributes);
  renderUsedCounter(&js, "entityByIdAttributeByName",                 noOfEntityByIdAttributeByName);
  renderUsedCounter(&js, "ctxEntityTypes",                            noOfContextEntityTypes);
  renderUsedCounter(&js, "ctxEntityTypeAttributeContainer",           noOfContextEntityTypeAttributeContainer);
  renderUsedCounter(&js, "ctxEntityTypeAttribute",                    noOfContextEntityTypeAttribute);
  renderUsedCounter(&js, "individualContextEntity",                   noOfIndividualContextEntity);
  renderUsedCounter(&js, "individualContextEntityAttributes",         noOfIndividualContextEntityAttributes);
  renderUsedCounter(&js, "individualContextEntityAttribute",          noOfIndividualContextEntityAttribute);
  renderUsedCounter(&js, "updateContextElement",                      noOfUpdateContextElement);
  renderUsedCounter(&js, "appendContextElement",                      noOfAppendContextElement);
  renderUsedCounter(&js, "updateContextAttribute",                    noOfUpdateContextAttribute);
  renderUsedCounter(&js, "ctxEntityTypesNgsi10",                      noOfNgsi10ContextEntityTypes);
  renderUsedCounter(&js, "ctxEntityTypeAttributeContainerNgsi10",     noOfNgsi10ContextEntityTypesAttributeContainer);
  renderUsedCounter(&js, "ctxEntityTypeAttributeNgsi10",              noOfNgsi10ContextEntityTypesAttribute);
  renderUsedCounter(&js, "subscriptionsNgsi10ConvOp",                 noOfNgsi10SubscriptionsConvOp);
  renderUsedCounter(&js, "allContextEntitiesRequests",                noOfAllContextEntitiesRequests);
  renderUsedCounter(&js, "allEntitiesWithTypeAndIdRequests",          noOfAllEntitiesWithTypeAndIdRequests);
  renderUsedCounter(&js, "individualCtxEntityAttributeWithTypeAndId", noOfIndividualContextEntityAttributeWithTypeAndId);
  renderUsedCounter(&js, "attributeValueInstanceWithTypeAndId",       noOfAttributeValueInstanceWithTypeAndId);
  renderUsedCounter(&js, "contextEntitiesByEntityIdAndType",          noOfContextEntitiesByEntityIdAndType);
  renderUsedCounter(&js, "entityByIdAttributeByNameIdAndType",        noOfEntityByIdAttributeByNameIdAndType);
  renderUsedCounter(&js, "logRequests", noOfLogRequests);

  //
  // The valgrind test suite uses REST GET /version to check that the broker is alive
  // This fact makes the statistics change and some working functests fail under valgrindTestSuite
  // due to the 'extra' version-request in the statistics.
  // Instead of removing version-requests from the statistics,
  // we report the number of version-requests even if zero (-1).
  //
  js.addNumber("versionRequests", noOfVersionRequests + 1);

  renderUsedCounter(&js, "exitRequests", noOfExitRequests);
  renderUsedCounter(&js, "leakRequests", noOfLeakRequests);
  renderUsedCounter(&js, "statisticsRequests", noOfStatisticsRequests);
  renderUsedCounter(&js, "invalidRequests", noOfInvalidRequests);
  renderUsedCounter(&js, "registerResponses", noOfRegisterResponses);
  renderUsedCounter(&js, "registrationErrors", noOfRegistrationErrors);
  renderUsedCounter(&js, "registrationUpdateErrors", noOfRegistrationUpdateErrors);
  renderUsedCounter(&js, "discoveryErrors", noOfDiscoveryErrors);

  return js.str();
}

/* ****************************************************************************
*
*  - renderSemWaitStats
*/
std::string renderSemWaitStats(void)
{
  JsonHelper jh;

  jh.addFloat("request",           semTimeReqGet());
  jh.addFloat("dbConnectionPool",  mongoPoolConnectionSemWaitingTimeGet());
  jh.addFloat("transaction",       semTimeTransGet());
  jh.addFloat("subCache",          semTimeCacheGet());
  jh.addFloat("connectionContext", mutexTimeCCGet());
  jh.addFloat("timeStat",          semTimeTimeStatGet());

  return jh.str();
}

/* ****************************************************************************
*
*  - renderNotifQueueStats
*/
std::string renderNotifQueueStats(void)
{
  JsonHelper jh;
  float      timeInQ = QueueStatistics::getTimeInQ();
  int        out     = QueueStatistics::getOut();

  jh.addNumber("in",             QueueStatistics::getIn());
  jh.addNumber("out",            out);
  jh.addNumber("reject",         QueueStatistics::getReject());
  jh.addNumber("sentOk",         QueueStatistics::getSentOK());     // FIXME P7: this needs to be generalized for all notificationModes
  jh.addNumber("sentError",      QueueStatistics::getSentError());  // FIXME P7: this needs to be generalized for all notificationModes
  jh.addFloat ("timeInQueue",    timeInQ);
  jh.addFloat ("avgTimeInQueue", out==0 ? 0 : (timeInQ/out));
  jh.addNumber("size",           QueueStatistics::getQSize());

  return jh.str();
}

/* ****************************************************************************
*
* xmlUseError -
*/
static std::string xmlUseError(void)
{
  std::string out = "";

  out += startTag("", "orion", "", XML, false, false, false);
  out += valueTag("  ", "message", "XML not supported in statistics operations, use JSON", XML);
  out += endTag("", "orion", XML, false, false, true, false);

  return out;
}

/* ****************************************************************************
*
* statisticsTreat -
*/
std::string statisticsTreat
(
  ConnectionInfo*            ciP,
  int                        components,
  std::vector<std::string>&  compV,
  ParseData*                 parseDataP
)
{
  if (ciP->outFormat == XML)
  {
    return xmlUseError();
  }

  JsonHelper js;

  if (ciP->method == "DELETE")
  {
    resetStatistics();
    js.addString("message", "All statistics counter reset");
    return js.str();
  }

  /* Conditional statistics (in the same order as described in statistics.md, although
   * beautifier tools may change this order */
  if (countersStatistics)
  {
    js.addRaw("counters", renderCounterStats());
  }
  if (semWaitStatistics)
  {
    js.addRaw("semWait", renderSemWaitStats());
  }
  if (timingStatistics)
  {
    js.addRaw("timing", renderTimingStatistics());
  }
  if ((notifQueueStatistics) && (strcmp(notificationMode, "threadpool") == 0))
  {
    js.addRaw("notifQueue", renderNotifQueueStats());
  }

  // Unconditional stats
  int now = getCurrentTime();
  js.addNumber("uptime_in_secs", now - startTime);
  js.addNumber("measuring_interval_in_secs", now - statisticsTime);

  // Special case: simulated notifications
  int nSimNotif = __sync_fetch_and_add(&noOfSimulatedNotifications, 0);
  renderUsedCounter(&js, "simulatedNotifications", nSimNotif);

  ciP->httpStatusCode = SccOk;
  return js.str();

}

/* ****************************************************************************
*
* statisticsCacheTreat -
*
*/
std::string statisticsCacheTreat
(
  ConnectionInfo*            ciP,
  int                        components,
  std::vector<std::string>&  compV,
  ParseData*                 parseDataP
)
{
  if (ciP->outFormat == XML)
  {
    return xmlUseError();
  }

  JsonHelper js;

  if (ciP->method == "DELETE")
  {
    subCacheStatisticsReset("statisticsTreat::DELETE");
    js.addString("message", "All statistics counter reset");
    return js.str();
  }

  //
  // mongo sub cache counters
  //
  int   mscRefreshs = 0;
  int   mscInserts  = 0;
  int   mscRemoves  = 0;
  int   mscUpdates  = 0;
  int   cacheItems  = 0;
  char  listBuffer[1024];

  cacheSemTake(__FUNCTION__, "statisticsCacheTreat");
  subCacheStatisticsGet(&mscRefreshs, &mscInserts, &mscRemoves, &mscUpdates, &cacheItems, listBuffer, sizeof(listBuffer));
  cacheSemGive(__FUNCTION__, "statisticsCacheTreat");

  js.addString("ids", listBuffer);    // FIXME P10: this seems not printing anything... is listBuffer working fine?
  js.addNumber("refresh", mscRefreshs);
  js.addNumber("inserts", mscInserts);
  js.addNumber("removes", mscRemoves);
  js.addNumber("updates", mscUpdates);
  js.addNumber("items", cacheItems);

  ciP->httpStatusCode = SccOk;
  return js.str();
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 LinBox
 * This file is part of the library LinBox. See COPYING for license info.
 * Written by bds.
 */
/** @file tests/checker.C
    @brief script to run LinBox tests

    Checker is compiled and run by the check macro invoked by "make fullcheck" in the top source dir or in tests/.

    Run without args,
    each test is build and run, with a one line report of success or failure.
    A summary at the end reports number of test failing to compile, failing at runtime, and skipped.
    There should be a 1-1 correspondence between files tests/test-*.C and report lines

    A LinBox unit/regresssion test has a default behaviour -- when there are no command line file names -- in which nothing is written to any output stream and the return value is 0 for a passing test, nonzero for any failure.

    The current convention is that (1) linbox' checker.C, runs the tests with no command line parameters at all, and (2) if there is a command line file name, verbose diagnostic output is written to that file and more terse output may be written to standard output streams.  The second feature is intended to assist debugging with individual tests.

*/

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <set>
#include <vector>
//#include <iomanip>
using namespace std;
//#include "linbox-config.h"
#include "linbox/linbox-config.h"
//#include "fflas-ffpack/fflas-ffpack.h"

// globals
//map< string, string> skip_note;
map< string, string> warn_note;
set< string> skips;
set< string> hides;
void warn(const string& t, const string& w) { warn_note[t] = w; }
void skip(const string& t, const string& w) { warn_note[t] = w; skips.insert(t); }
void hide(const string& t, const string& w) { warn_note[t] = w; hides.insert(t); }

int main(int argc, char* argv[]) {
	int arg;
	bool force_build = false, reporting = true, honor_skips = true;
	for (arg = 1; arg < argc; ++arg)
		for (char * i = argv[arg]; *i != 0; ++i){
			if (*i == 'r') force_build = true;
			if (*i == 's') reporting = false;
			if (*i == 'a') honor_skips = false;
		}
    if (argc > 1 and not force_build and reporting and honor_skips){ // bogus arg
		cout << "usage: " << argv[0] << " [-][r][s][a]" << endl;
		cout << "  -r Force recompilation of each test."<< endl;
		cout << "  -s Summary only: 3 lines printed. (Default is one line per test.)" << endl;
		cout << "  -a Build and run all. (Ignore skip and hide commands.)" << endl;
		return 0;
	}

// fullcheck customization: warnings, skips, hides, optional package dependencies

//// notes section (customize fullcheck here) ////

    if (honor_skips) {
        hide("test-block-ring", "non commutative rings not supported");
//hide("test-ffpack", "testTURBO fails, move to ffpack tests?");
        hide("test-ftrmm", "should move to attic");
        skip("test-givaro-fields", "may fail on small fields because of supposed non-randomness or failure to find a non trivial element");
        hide("test-image-field", "deprecated");
// skip("test-invariant-factors", "not unit/regression test conforming");
//skip("test-isposdef", "intermittent inf loop");
//skip("test-ispossemidef", "intermittent inf loop");
        hide("test-la-block-lanczos", "not maintained. operator >> missing");
        hide("test-mg-block-lanczos", "not maintained");
        hide("test-modular", "deprecated");
        hide("test-modular-byte",  "deprecated");
        hide("test-modular-short",  "deprecated");
//skip("test-modular-balanced-int",  "test and modular-balanced disagree on init/convert");
//skip("test-modular-balanced-double",  "test and modular-balanced disagree on init/convert");
//skip("test-moore-penrose", "inf loop");
        skip("test-optimization", "not unit/regression test conforming");
//skip("test-rational-reconstruction-base", "inf loop");
        skip("test-rat-charpoly", "inf loop");
        skip("test-rat-minpoly", "stale test. solns over QQ need fresh tests"); // "intermittent failures")
        skip("test-rat-solve", "stale test. solns over QQ need fresh tests"); // "infinite loop")
        skip("test-poly-det", "incomplete test (if still relevant)");
        skip("test-sparse-map-map", "const issue in givranditer, curious use of nonexistant next() in Extension");
//Tests requiring further development
    }

//warn("test-echelon-form", "new");
    warn("test-fibb",  "incomplete");
//warn("test-matrix-domain", "intermittent row permutation failure");
    warn("test-param-fuzzy", "Noncompliant field");
//		template <class F2Field> BitVector (const F2Field&) {}
//warn("test-qlup", "GF2 fails to compile");
//warn("test-rank-u32", "intermittent failure"/*, "vector (bb) responsible"*/);
    warn("test-rat-charpoly", "stale test. solns over QQ need fresh tests");//, "infinite loop, cp responsible?")
    warn("test-rat-solve", "infinite loop");
//warn("test-smith-form-local", "bds, intermittent failures");
    warn("test-solve", "most of the tests are commented out");
    warn("test-toom-cook", " One method does not work");
//warn("test-transpose", "sometimes fails on Sparsematrix/getEntry");
/* Quad matrix is a dormant project. Eventual revival is expected. Test works.
    warn("test-quad-matrix", "half baked, bds responsible");
*/

    skip("test-smith-form-kannan-bachem", " not working anymore");
    warn("test-one-invariant-factor", " Probabilistic algorithm, sometimes fails");

//// optional package dependency section ////
	set< string> ntl_tests;
	ntl_tests.insert("test-ntl-hankel");
	ntl_tests.insert("test-ntl-lzz_p");
	ntl_tests.insert("test-ntl-lzz_pe");
	ntl_tests.insert("test-ntl-lzz_px");
	ntl_tests.insert("test-ntl-lzz_pex");
	warn("test-toeplitz", "we should have a non NTL version.");
	ntl_tests.insert("test-toeplitz");
	warn("test-toeplitz-det", "we should have a non NTL version.");
	ntl_tests.insert("test-toeplitz-det");
	warn("test-ntl-rr", "floating point equality");
	ntl_tests.insert("test-ntl-rr");
	ntl_tests.insert("test-ntl-sylvester");
	ntl_tests.insert("test-ntl-toeplitz");
	ntl_tests.insert("test-ntl-zz_p");

        // are these really ntl dependent?
//	ntl_tests.insert("test-smith-form");
//	ntl_tests.insert("test-smith-form-adaptive");
//	ntl_tests.insert("test-smith-form-iliopoulos");
	ntl_tests.insert("test-polynomial-local-x");
	ntl_tests.insert("test-weak-popov-form");
	ntl_tests.insert("test-frobenius-large");
	ntl_tests.insert("test-invariant-factors");
	ntl_tests.insert("test-frobenius-small");
	ntl_tests.insert("test-poly-smith-form");

	set< string> ocl_tests;
	ocl_tests.insert("test-opencl-domain");

    set<string> mpi_tests;
    mpi_tests.insert("test-mpi-comm");
//// Things are automatic from here onward. ////

        // process optional dependencies
#ifndef LINBOX_HAVE_OCL
    for (set< string>::iterator i = ocl_tests.begin(); i != ocl_tests.end(); ++i)
		skip(*i, "OpenCL not present");
#endif
#ifndef __LINBOX_HAVE_NTL
    for (set< string>::iterator i = ntl_tests.begin(); i != ntl_tests.end(); ++i)
		skip(*i, "NTL not present");
#endif
#ifndef LINBOX_HAVE_MPI
    for (set< string>::iterator i = mpi_tests.begin(); i != mpi_tests.end(); ++i)
		skip(*i, "MPI not present");
#endif
// build and run the tests section
	string t, cmd;
	system("ls test-*C >.tmp-tests");
	ifstream tests(".tmp-tests");
	int buildfail = 0, runfail = 0, skipped = 0, pass = 0; // counts
	vector<string> all_tests;
	while (tests >> t) {t.resize(t.size()-2); all_tests.push_back(t);}
//#ifdef LINBOX_HAVE_OPENMP
//#pragma omp parallel for
//PARFOR1D(i, 0, all_tests.size(), SPLITTER(),
//#endif
	for (size_t i = 0; i < all_tests.size(); ++i)
	{
		t = all_tests[i];
		if (hides.count(t) > 0) continue; // ignore entirely
		stringstream report;
		report.width(35);
		report << left << t;
		if (skips.count(t) > 0) { // print skip message
			report << "skipped, " + warn_note[t];
			skipped++;
		} else { // do build
			if (force_build) {
				cmd = "touch " + t + ".C";
				system(cmd.c_str());
			}
                // build
			cmd = "make " + t + " 2> /dev/null > /dev/null";
			report << "build ";
			int status = system(cmd.c_str());
//			#ifndef LINBOX_HAVE_OPENMP
//			if (status == 2) break;
//			#endif
			if (status != 0) { // build failure
				buildfail++;
				report << "FAIL. ";
			} else {// do run
				report << "OK, run ";
				std::ostringstream prog ;
				prog << "./" << t ;
				status = system(prog.str().c_str());
//				#ifndef LINBOX_HAVE_OPENMP
//				if (status == 2) break;
//				#endif
				if (status == 0) {
					report << "OK.  " + warn_note[t];
					pass++;
				} else {
					runfail++;
					report << "FAIL. " + warn_note[t];
				}
			}
		}
		if (reporting) cout << report.str() << endl;
	} // for i
        //); // parfor

        //// summary ////
	cout << "--------------------------------------------------------------------" << endl;
	int total = pass + buildfail + runfail + skipped;
	if (buildfail || runfail)
		cout << "Of " << total << " tests, "
             << pass << " passed, "
             << buildfail << " failed to compile, "
             << runfail << " failed at runtime, "
             << " and " << skipped << " were skipped." << endl;
	else
		cout << endl << "All " << total - skipped << " tests pass."
             << "  (There were " << skipped << " skipped tests.)" << endl;
	cout << "--------------------------------------------------------------------" << endl;

	return buildfail || runfail ? -1 : 0;
} // main

// Local Variables:
// mode: C++
// tab-width: 4
// indent-tabs-mode: nil
// c-basic-offset: 4
// End:
// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
<commit_msg>KB OK<commit_after>/*
 * Copyright (c) 2015 LinBox
 * This file is part of the library LinBox. See COPYING for license info.
 * Written by bds.
 */
/** @file tests/checker.C
    @brief script to run LinBox tests

    Checker is compiled and run by the check macro invoked by "make fullcheck" in the top source dir or in tests/.

    Run without args,
    each test is build and run, with a one line report of success or failure.
    A summary at the end reports number of test failing to compile, failing at runtime, and skipped.
    There should be a 1-1 correspondence between files tests/test-*.C and report lines

    A LinBox unit/regresssion test has a default behaviour -- when there are no command line file names -- in which nothing is written to any output stream and the return value is 0 for a passing test, nonzero for any failure.

    The current convention is that (1) linbox' checker.C, runs the tests with no command line parameters at all, and (2) if there is a command line file name, verbose diagnostic output is written to that file and more terse output may be written to standard output streams.  The second feature is intended to assist debugging with individual tests.

*/

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <set>
#include <vector>
//#include <iomanip>
using namespace std;
//#include "linbox-config.h"
#include "linbox/linbox-config.h"
//#include "fflas-ffpack/fflas-ffpack.h"

// globals
//map< string, string> skip_note;
map< string, string> warn_note;
set< string> skips;
set< string> hides;
void warn(const string& t, const string& w) { warn_note[t] = w; }
void skip(const string& t, const string& w) { warn_note[t] = w; skips.insert(t); }
void hide(const string& t, const string& w) { warn_note[t] = w; hides.insert(t); }

int main(int argc, char* argv[]) {
	int arg;
	bool force_build = false, reporting = true, honor_skips = true;
	for (arg = 1; arg < argc; ++arg)
		for (char * i = argv[arg]; *i != 0; ++i){
			if (*i == 'r') force_build = true;
			if (*i == 's') reporting = false;
			if (*i == 'a') honor_skips = false;
		}
    if (argc > 1 and not force_build and reporting and honor_skips){ // bogus arg
		cout << "usage: " << argv[0] << " [-][r][s][a]" << endl;
		cout << "  -r Force recompilation of each test."<< endl;
		cout << "  -s Summary only: 3 lines printed. (Default is one line per test.)" << endl;
		cout << "  -a Build and run all. (Ignore skip and hide commands.)" << endl;
		return 0;
	}

// fullcheck customization: warnings, skips, hides, optional package dependencies

//// notes section (customize fullcheck here) ////

    if (honor_skips) {
        hide("test-block-ring", "non commutative rings not supported");
//hide("test-ffpack", "testTURBO fails, move to ffpack tests?");
        hide("test-ftrmm", "should move to attic");
//         skip("test-givaro-fields", "may fail on small fields because of supposed non-randomness or failure to find a non trivial element");
        hide("test-image-field", "deprecated");
// skip("test-invariant-factors", "not unit/regression test conforming");
//skip("test-isposdef", "intermittent inf loop");
//skip("test-ispossemidef", "intermittent inf loop");
        hide("test-la-block-lanczos", "not maintained. operator >> missing");
        hide("test-mg-block-lanczos", "not maintained");
        hide("test-modular", "deprecated");
        hide("test-modular-byte",  "deprecated");
        hide("test-modular-short",  "deprecated");
//skip("test-modular-balanced-int",  "test and modular-balanced disagree on init/convert");
//skip("test-modular-balanced-double",  "test and modular-balanced disagree on init/convert");
//skip("test-moore-penrose", "inf loop");
        skip("test-optimization", "not unit/regression test conforming");
//skip("test-rational-reconstruction-base", "inf loop");
        skip("test-rat-charpoly", "inf loop");
        skip("test-rat-minpoly", "stale test. solns over QQ need fresh tests"); // "intermittent failures")
        skip("test-rat-solve", "stale test. solns over QQ need fresh tests"); // "infinite loop")
        skip("test-poly-det", "incomplete test (if still relevant)");
        skip("test-sparse-map-map", "const issue in givranditer, curious use of nonexistant next() in Extension");
//Tests requiring further development
    }

//warn("test-echelon-form", "new");
    warn("test-fibb",  "incomplete");
//warn("test-matrix-domain", "intermittent row permutation failure");
    warn("test-param-fuzzy", "Noncompliant field");
//		template <class F2Field> BitVector (const F2Field&) {}
//warn("test-qlup", "GF2 fails to compile");
//warn("test-rank-u32", "intermittent failure"/*, "vector (bb) responsible"*/);
    warn("test-rat-charpoly", "stale test. solns over QQ need fresh tests");//, "infinite loop, cp responsible?")
    warn("test-rat-solve", "infinite loop");
//warn("test-smith-form-local", "bds, intermittent failures");
    warn("test-solve", "most of the tests are commented out");
    warn("test-toom-cook", " One method does not work");
//warn("test-transpose", "sometimes fails on Sparsematrix/getEntry");
/* Quad matrix is a dormant project. Eventual revival is expected. Test works.
    warn("test-quad-matrix", "half baked, bds responsible");
*/

    warn("test-one-invariant-factor", " Probabilistic algorithm, sometimes fails");

//// optional package dependency section ////
	set< string> ntl_tests;
	ntl_tests.insert("test-ntl-hankel");
	ntl_tests.insert("test-ntl-lzz_p");
	ntl_tests.insert("test-ntl-lzz_pe");
	ntl_tests.insert("test-ntl-lzz_px");
	ntl_tests.insert("test-ntl-lzz_pex");
	warn("test-toeplitz", "we should have a non NTL version.");
	ntl_tests.insert("test-toeplitz");
	warn("test-toeplitz-det", "we should have a non NTL version.");
	ntl_tests.insert("test-toeplitz-det");
	warn("test-ntl-rr", "floating point equality");
	ntl_tests.insert("test-ntl-rr");
	ntl_tests.insert("test-ntl-sylvester");
	ntl_tests.insert("test-ntl-toeplitz");
	ntl_tests.insert("test-ntl-zz_p");

        // are these really ntl dependent?
//	ntl_tests.insert("test-smith-form");
//	ntl_tests.insert("test-smith-form-adaptive");
//	ntl_tests.insert("test-smith-form-iliopoulos");
	ntl_tests.insert("test-polynomial-local-x");
	ntl_tests.insert("test-weak-popov-form");
	ntl_tests.insert("test-frobenius-large");
	ntl_tests.insert("test-invariant-factors");
	ntl_tests.insert("test-frobenius-small");
	ntl_tests.insert("test-poly-smith-form");

	set< string> ocl_tests;
	ocl_tests.insert("test-opencl-domain");

    set<string> mpi_tests;
    mpi_tests.insert("test-mpi-comm");
//// Things are automatic from here onward. ////

        // process optional dependencies
#ifndef LINBOX_HAVE_OCL
    for (set< string>::iterator i = ocl_tests.begin(); i != ocl_tests.end(); ++i)
		skip(*i, "OpenCL not present");
#endif
#ifndef __LINBOX_HAVE_NTL
    for (set< string>::iterator i = ntl_tests.begin(); i != ntl_tests.end(); ++i)
		skip(*i, "NTL not present");
#endif
#ifndef LINBOX_HAVE_MPI
    for (set< string>::iterator i = mpi_tests.begin(); i != mpi_tests.end(); ++i)
		skip(*i, "MPI not present");
#endif
// build and run the tests section
	string t, cmd;
	system("ls test-*C >.tmp-tests");
	ifstream tests(".tmp-tests");
	int buildfail = 0, runfail = 0, skipped = 0, pass = 0; // counts
	vector<string> all_tests;
	while (tests >> t) {t.resize(t.size()-2); all_tests.push_back(t);}
//#ifdef LINBOX_HAVE_OPENMP
//#pragma omp parallel for
//PARFOR1D(i, 0, all_tests.size(), SPLITTER(),
//#endif
	for (size_t i = 0; i < all_tests.size(); ++i)
	{
		t = all_tests[i];
		if (hides.count(t) > 0) continue; // ignore entirely
		stringstream report;
		report.width(35);
		report << left << t;
		if (skips.count(t) > 0) { // print skip message
			report << "skipped, " + warn_note[t];
			skipped++;
		} else { // do build
			if (force_build) {
				cmd = "touch " + t + ".C";
				system(cmd.c_str());
			}
                // build
			cmd = "make " + t + " 2> /dev/null > /dev/null";
			report << "build ";
			int status = system(cmd.c_str());
//			#ifndef LINBOX_HAVE_OPENMP
//			if (status == 2) break;
//			#endif
			if (status != 0) { // build failure
				buildfail++;
				report << "FAIL. ";
			} else {// do run
				report << "OK, run ";
				std::ostringstream prog ;
				prog << "./" << t ;
				status = system(prog.str().c_str());
//				#ifndef LINBOX_HAVE_OPENMP
//				if (status == 2) break;
//				#endif
				if (status == 0) {
					report << "OK.  " + warn_note[t];
					pass++;
				} else {
					runfail++;
					report << "FAIL. " + warn_note[t];
				}
			}
		}
		if (reporting) cout << report.str() << endl;
	} // for i
        //); // parfor

        //// summary ////
	cout << "--------------------------------------------------------------------" << endl;
	int total = pass + buildfail + runfail + skipped;
	if (buildfail || runfail)
		cout << "Of " << total << " tests, "
             << pass << " passed, "
             << buildfail << " failed to compile, "
             << runfail << " failed at runtime, "
             << " and " << skipped << " were skipped." << endl;
	else
		cout << endl << "All " << total - skipped << " tests pass."
             << "  (There were " << skipped << " skipped tests.)" << endl;
	cout << "--------------------------------------------------------------------" << endl;

	return buildfail || runfail ? -1 : 0;
} // main

// Local Variables:
// mode: C++
// tab-width: 4
// indent-tabs-mode: nil
// c-basic-offset: 4
// End:
// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
<|endoftext|>


<commit_before>// -*- c-basic-offset: 2; related-file-name: "" -*-
/*
 * @(#)$Id$
 *
 * Copyright (c) 2004 Intel Corporation. All rights reserved.
 *
 * This file is distributed under the terms in the attached INTEL-LICENSE file.
 * If you do not find these files, copies can be found by writing to:
 * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300,
 * Berkeley, CA, 94704.  Attention:  Intel License Inquiry.
 *
 * DESCRIPTION: Test harness for datalog....
 *
 */

#include <async.h>
#include <arpc.h>
#include <iostream>
#include <fstream>
#include <string>

#include "ol_lexer.h"
#include "ol_context.h"
#include "rtr_confgen.h"
// #include "routerConfigGenerator.h"
#include "udp.h"

extern int ol_parser_debug;

int main(int argc, char **argv)
{
  std::cout << "OVERLOG\n";
  ref< OL_Context > ctxt = New refcounted< OL_Context>();
  bool route = false;
  bool builtin = false;

  for( int i=1; i<argc; i++) {
    std::string arg(argv[i]);

    if (arg == "-d") {
      ol_parser_debug = 1;
    } else if (arg == "-h") {
      std::cerr << "Usage: " << argv[0] << "{option|filename}+\n"
		<< "\t-c: canonical form (used for builtin tests)\n"
		<< "\t-d: turn on parser debugging\n"
		<< "\t-r: try to instantiate a router config\n"
		<< "\t-h: print this help text\n"
		<< "\t- : read from stdin\n";
      exit(0);
    } else if (arg == "-c") {
      builtin = true;
    } else if (arg == "-r") {
      route = true;
      builtin = false;
    } else if (arg == "-") {
      ctxt->parse_stream(&std::cin);
    } else {
      std::ifstream istr(argv[i]);
      ctxt->parse_stream(&istr);
    }
  }

  if (builtin) {
    std::cerr << ctxt->toString();
    std::cerr.flush();
    std::cout << "OK\n";
    std::cout.flush();
  }

  std::cout << "Finish parsing (functors / tableInfos) " << ctxt->getFunctors()->size()
	    << " " << ctxt->getTableInfos()->size() << "\n";

  if (route) {
    // test a configuration of a router
    Router::ConfigurationRef conf = New refcounted< Router::Configuration >();
    Rtr_ConfGen gen(ctxt, conf, true, true, "test config");
    gen.createTables("localhost");

    ref< Udp > udp = New refcounted< Udp >("Udp", 10000);
    gen.configureRouter(udp, "localhost:10000");

    LoggerI::Level level = LoggerI::NONE;
    RouterRef router = New refcounted< Router >(conf, level);
    if (router->initialize(router) == 0) {
      std::cout << "Correctly initialized network of reachability flows.\n";
    } else {
      std::cout << "** Failed to initialize correct spec\n";
    }
  }
  std::cout << "Done.\n";

  return 0;
}
<commit_msg>overlog<commit_after>// -*- c-basic-offset: 2; related-file-name: "" -*-
/*
 * @(#)$Id$
 *
 * Copyright (c) 2004 Intel Corporation. All rights reserved.
 *
 * This file is distributed under the terms in the attached INTEL-LICENSE file.
 * If you do not find these files, copies can be found by writing to:
 * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300,
 * Berkeley, CA, 94704.  Attention:  Intel License Inquiry.
 *
 * DESCRIPTION: Test harness for datalog....
 *
 */

#include <async.h>
#include <arpc.h>
#include <iostream>
#include <fstream>
#include <string>

#include "ol_lexer.h"
#include "ol_context.h"
#include "rtr_confgen.h"
// #include "routerConfigGenerator.h"
#include "udp.h"

extern int ol_parser_debug;

int main(int argc, char **argv)
{
  std::cout << "OVERLOG\n";
  ref< OL_Context > ctxt = New refcounted< OL_Context>();
  bool route = false;
  bool builtin = false;
  str filename("");

  for( int i=1; i<argc; i++) {
    std::string arg(argv[i]);

    if (arg == "-d") {
      ol_parser_debug = 1;
    } else if (arg == "-h") {
      std::cerr << "Usage: " << argv[0] << "{option|filename}+\n"
		<< "\t-c: canonical form (used for builtin tests)\n"
		<< "\t-d: turn on parser debugging\n"
		<< "\t-r: try to instantiate a router config\n"
		<< "\t-h: print this help text\n"
		<< "\t- : read from stdin\n";
      exit(0);
    } else if (arg == "-c") {
      builtin = true;
    } else if (arg == "-r") {
      route = true;
      builtin = false;
    } else if (arg == "-") {
      ctxt->parse_stream(&std::cin);
    } else {
      filename = argv[i];
      std::ifstream istr(argv[i]);
      ctxt->parse_stream(&istr);
    }
  }

  if (builtin) {
    std::cerr << ctxt->toString();
    std::cerr.flush();
    std::cout << "OK\n";
    std::cout.flush();
  }

  std::cout << "Finish parsing (functors / tableInfos) " << ctxt->getFunctors()->size()
	    << " " << ctxt->getTableInfos()->size() << "\n";

  if (route) {
    // test a configuration of a router
    Router::ConfigurationRef conf = New refcounted< Router::Configuration >();
    Rtr_ConfGen gen(ctxt, conf, false, false, filename);
    gen.createTables("127.0.0.1:10000");

    ref< Udp > udp = New refcounted< Udp >("Udp", 10000);
    gen.configureRouter(udp, "127.0.0.1:10000");

    LoggerI::Level level = LoggerI::NONE;
    RouterRef router = New refcounted< Router >(conf, level);
    if (router->initialize(router) == 0) {
      std::cout << "Correctly initialized network of reachability flows.\n";
    } else {
      std::cout << "** Failed to initialize correct spec\n";
    }
  }
  std::cout << "Done.\n";

  return 0;
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2013, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "test.hpp"
#include "setup_transfer.hpp"
#include "dht_server.hpp"
#include "peer_server.hpp"
#include "libtorrent/alert.hpp"
#include "libtorrent/alert_types.hpp"

#include <fstream>

using namespace libtorrent;

char const* proxy_name[] = {
	"none",
	"socks4",
	"socks5",
	"socks5_pw",
	"http",
	"http_pw",
	"i2p_proxy"
};

std::vector<std::string> rejected_trackers;

bool alert_predicate(libtorrent::alert* a)
{
	anonymous_mode_alert* am = alert_cast<anonymous_mode_alert>(a);
	if (am == NULL) return false;

	if (am->kind == anonymous_mode_alert::tracker_not_anonymous)
		rejected_trackers.push_back(am->str);

	return false;
}

enum flags_t
{
	anonymous_mode = 1,
	expect_http_connection = 2,
	expect_udp_connection = 4,
	expect_http_reject = 8,
	expect_udp_reject = 16,
	expect_dht_msg = 32,
	expect_peer_connection = 64,
};

void test_proxy(proxy_settings::proxy_type proxy_type, int flags)
{
	fprintf(stderr, "\n=== TEST == proxy: %s anonymous-mode: %s\n\n", proxy_name[proxy_type], (flags & anonymous_mode) ? "yes" : "no");
	int http_port = start_web_server();
	int udp_port = start_tracker();
	int dht_port = start_dht();
	int peer_port = start_peer();

	int prev_udp_announces = g_udp_tracker_requests;
	int prev_http_announces = g_http_tracker_requests;

	int const alert_mask = alert::all_categories
		& ~alert::progress_notification
		& ~alert::stats_notification;

	session* s = new libtorrent::session(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48875, 49800), "0.0.0.0", 0, alert_mask);

	session_settings sett;
	sett.stop_tracker_timeout = 1;
	sett.tracker_completion_timeout = 1;
	sett.tracker_receive_timeout = 1;
	sett.half_open_limit = 1;
	sett.announce_to_all_trackers = true;
	sett.announce_to_all_tiers = true;
	sett.anonymous_mode = flags & anonymous_mode;
	sett.force_proxy = flags & anonymous_mode;

	// if we don't do this, the peer connection test
	// will be delayed by several seconds, by first
	// trying uTP
	sett.enable_outgoing_utp = false;
	s->set_settings(sett);

	proxy_settings ps;
	ps.hostname = "non-existing.com";
	ps.port = 4444;
	ps.type = proxy_type;
	s->set_proxy(ps);

	s->start_dht();

	error_code ec;
	create_directory("tmp1_privacy", ec);
	std::ofstream file(combine_path("tmp1_privacy", "temporary").c_str());
	boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file, 16 * 1024, 13, false);
	file.close();

	char http_tracker_url[200];
	snprintf(http_tracker_url, sizeof(http_tracker_url), "http://127.0.0.1:%d/announce", http_port);
	t->add_tracker(http_tracker_url, 0);

	char udp_tracker_url[200];
	snprintf(udp_tracker_url, sizeof(udp_tracker_url), "udp://127.0.0.1:%d/announce", udp_port);
	t->add_tracker(udp_tracker_url, 1);

	add_torrent_params addp;
	addp.flags &= ~add_torrent_params::flag_paused;
	addp.flags &= ~add_torrent_params::flag_auto_managed;
	addp.ti = t;
	addp.save_path = "tmp1_privacy";
	addp.dht_nodes.push_back(std::pair<std::string, int>("127.0.0.1", dht_port));
	torrent_handle h = s->add_torrent(addp);

	printf("connect_peer: 127.0.0.1:%d\n", peer_port);
	h.connect_peer(tcp::endpoint(address_v4::from_string("127.0.0.1"), peer_port));

	rejected_trackers.clear();
	for (int i = 0; i < 15; ++i)
	{
		print_alerts(*s, "s", false, false, false, &alert_predicate);
		test_sleep(100);

		if (g_udp_tracker_requests >= prev_udp_announces + 1
			&& g_http_tracker_requests >= prev_http_announces + 1
			&& num_peer_hits() > 0)
			break;
	}

	// we should have announced to the tracker by now
	TEST_EQUAL(g_udp_tracker_requests, prev_udp_announces + bool(flags & expect_udp_connection));
	TEST_EQUAL(g_http_tracker_requests, prev_http_announces + bool(flags & expect_http_connection));
	if (flags & expect_dht_msg)
	{
		TEST_CHECK(num_dht_hits() > 0);
	}
	else
	{
		TEST_EQUAL(num_dht_hits(), 0);
	}

	if (flags & expect_peer_connection)
	{
		TEST_CHECK(num_peer_hits() > 0);
	}
	else
	{
		TEST_EQUAL(num_peer_hits(), 0);
	}

	if (flags & expect_udp_reject)
		TEST_CHECK(std::find(rejected_trackers.begin(), rejected_trackers.end(), udp_tracker_url) != rejected_trackers.end());

	if (flags & expect_http_reject)
		TEST_CHECK(std::find(rejected_trackers.begin(), rejected_trackers.end(), http_tracker_url) != rejected_trackers.end());

	fprintf(stderr, "%s: ~session\n", time_now_string());
	delete s;
	fprintf(stderr, "%s: ~session done\n", time_now_string());

	stop_peer();
	stop_dht();
	stop_tracker();
	stop_web_server();
}

int test_main()
{
	// not using anonymous mode
	// UDP fails open if we can't connect to the proxy
	// or if the proxy doesn't support UDP
	test_proxy(proxy_settings::none, expect_udp_connection | expect_http_connection | expect_dht_msg | expect_peer_connection);
	test_proxy(proxy_settings::socks4, expect_udp_connection | expect_dht_msg);
	test_proxy(proxy_settings::socks5, expect_udp_connection | expect_dht_msg);
	test_proxy(proxy_settings::socks5_pw, expect_udp_connection | expect_dht_msg);
	test_proxy(proxy_settings::http, expect_udp_connection | expect_dht_msg);
	test_proxy(proxy_settings::http_pw, expect_udp_connection | expect_dht_msg);
	test_proxy(proxy_settings::i2p_proxy, expect_udp_connection | expect_dht_msg);

	// using anonymous mode

	// anonymous mode doesn't require a proxy when one isn't configured. It could be
	// used with a VPN for instance. This will all changed in 1.0, where anonymous
	// mode is separated from force_proxy
	test_proxy(proxy_settings::none, anonymous_mode | expect_peer_connection);
	test_proxy(proxy_settings::socks4, anonymous_mode | expect_udp_reject);
	test_proxy(proxy_settings::socks5, anonymous_mode);
	test_proxy(proxy_settings::socks5_pw, anonymous_mode);
	test_proxy(proxy_settings::http, anonymous_mode | expect_udp_reject);
	test_proxy(proxy_settings::http_pw, anonymous_mode | expect_udp_reject);
	test_proxy(proxy_settings::i2p_proxy, anonymous_mode);
	return 0;
}

<commit_msg>fix test_privacy when DHT is disabled<commit_after>/*

Copyright (c) 2013, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "test.hpp"
#include "setup_transfer.hpp"
#include "dht_server.hpp"
#include "peer_server.hpp"
#include "libtorrent/alert.hpp"
#include "libtorrent/alert_types.hpp"

#include <fstream>

using namespace libtorrent;

char const* proxy_name[] = {
	"none",
	"socks4",
	"socks5",
	"socks5_pw",
	"http",
	"http_pw",
	"i2p_proxy"
};

std::vector<std::string> rejected_trackers;

bool alert_predicate(libtorrent::alert* a)
{
	anonymous_mode_alert* am = alert_cast<anonymous_mode_alert>(a);
	if (am == NULL) return false;

	if (am->kind == anonymous_mode_alert::tracker_not_anonymous)
		rejected_trackers.push_back(am->str);

	return false;
}

enum flags_t
{
	anonymous_mode = 1,
	expect_http_connection = 2,
	expect_udp_connection = 4,
	expect_http_reject = 8,
	expect_udp_reject = 16,
	expect_dht_msg = 32,
	expect_peer_connection = 64,
};

void test_proxy(proxy_settings::proxy_type proxy_type, int flags)
{
#ifdef TORRENT_DISABLE_DHT
	// if DHT is disabled, we won't get any requests to it
	flags &= ~expect_dht_msg;
#endif
	fprintf(stderr, "\n=== TEST == proxy: %s anonymous-mode: %s\n\n", proxy_name[proxy_type], (flags & anonymous_mode) ? "yes" : "no");
	int http_port = start_web_server();
	int udp_port = start_tracker();
	int dht_port = start_dht();
	int peer_port = start_peer();

	int prev_udp_announces = g_udp_tracker_requests;
	int prev_http_announces = g_http_tracker_requests;

	int const alert_mask = alert::all_categories
		& ~alert::progress_notification
		& ~alert::stats_notification;

	session* s = new libtorrent::session(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48875, 49800), "0.0.0.0", 0, alert_mask);

	session_settings sett;
	sett.stop_tracker_timeout = 1;
	sett.tracker_completion_timeout = 1;
	sett.tracker_receive_timeout = 1;
	sett.half_open_limit = 1;
	sett.announce_to_all_trackers = true;
	sett.announce_to_all_tiers = true;
	sett.anonymous_mode = flags & anonymous_mode;
	sett.force_proxy = flags & anonymous_mode;

	// if we don't do this, the peer connection test
	// will be delayed by several seconds, by first
	// trying uTP
	sett.enable_outgoing_utp = false;
	s->set_settings(sett);

	proxy_settings ps;
	ps.hostname = "non-existing.com";
	ps.port = 4444;
	ps.type = proxy_type;
	s->set_proxy(ps);

	s->start_dht();

	error_code ec;
	create_directory("tmp1_privacy", ec);
	std::ofstream file(combine_path("tmp1_privacy", "temporary").c_str());
	boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file, 16 * 1024, 13, false);
	file.close();

	char http_tracker_url[200];
	snprintf(http_tracker_url, sizeof(http_tracker_url), "http://127.0.0.1:%d/announce", http_port);
	t->add_tracker(http_tracker_url, 0);

	char udp_tracker_url[200];
	snprintf(udp_tracker_url, sizeof(udp_tracker_url), "udp://127.0.0.1:%d/announce", udp_port);
	t->add_tracker(udp_tracker_url, 1);

	add_torrent_params addp;
	addp.flags &= ~add_torrent_params::flag_paused;
	addp.flags &= ~add_torrent_params::flag_auto_managed;
	addp.ti = t;
	addp.save_path = "tmp1_privacy";
	addp.dht_nodes.push_back(std::pair<std::string, int>("127.0.0.1", dht_port));
	torrent_handle h = s->add_torrent(addp);

	printf("connect_peer: 127.0.0.1:%d\n", peer_port);
	h.connect_peer(tcp::endpoint(address_v4::from_string("127.0.0.1"), peer_port));

	rejected_trackers.clear();
	for (int i = 0; i < 15; ++i)
	{
		print_alerts(*s, "s", false, false, false, &alert_predicate);
		test_sleep(100);

		if (g_udp_tracker_requests >= prev_udp_announces + 1
			&& g_http_tracker_requests >= prev_http_announces + 1
			&& num_peer_hits() > 0)
			break;
	}

	// we should have announced to the tracker by now
	TEST_EQUAL(g_udp_tracker_requests, prev_udp_announces + bool(flags & expect_udp_connection));
	TEST_EQUAL(g_http_tracker_requests, prev_http_announces + bool(flags & expect_http_connection));
	if (flags & expect_dht_msg)
	{
		TEST_CHECK(num_dht_hits() > 0);
	}
	else
	{
		TEST_EQUAL(num_dht_hits(), 0);
	}

	if (flags & expect_peer_connection)
	{
		TEST_CHECK(num_peer_hits() > 0);
	}
	else
	{
		TEST_EQUAL(num_peer_hits(), 0);
	}

	if (flags & expect_udp_reject)
		TEST_CHECK(std::find(rejected_trackers.begin(), rejected_trackers.end(), udp_tracker_url) != rejected_trackers.end());

	if (flags & expect_http_reject)
		TEST_CHECK(std::find(rejected_trackers.begin(), rejected_trackers.end(), http_tracker_url) != rejected_trackers.end());

	fprintf(stderr, "%s: ~session\n", time_now_string());
	delete s;
	fprintf(stderr, "%s: ~session done\n", time_now_string());

	stop_peer();
	stop_dht();
	stop_tracker();
	stop_web_server();
}

int test_main()
{
	// not using anonymous mode
	// UDP fails open if we can't connect to the proxy
	// or if the proxy doesn't support UDP
	test_proxy(proxy_settings::none, expect_udp_connection | expect_http_connection | expect_dht_msg | expect_peer_connection);
	test_proxy(proxy_settings::socks4, expect_udp_connection | expect_dht_msg);
	test_proxy(proxy_settings::socks5, expect_udp_connection | expect_dht_msg);
	test_proxy(proxy_settings::socks5_pw, expect_udp_connection | expect_dht_msg);
	test_proxy(proxy_settings::http, expect_udp_connection | expect_dht_msg);
	test_proxy(proxy_settings::http_pw, expect_udp_connection | expect_dht_msg);
	test_proxy(proxy_settings::i2p_proxy, expect_udp_connection | expect_dht_msg);

	// using anonymous mode

	// anonymous mode doesn't require a proxy when one isn't configured. It could be
	// used with a VPN for instance. This will all changed in 1.0, where anonymous
	// mode is separated from force_proxy
	test_proxy(proxy_settings::none, anonymous_mode | expect_peer_connection);
	test_proxy(proxy_settings::socks4, anonymous_mode | expect_udp_reject);
	test_proxy(proxy_settings::socks5, anonymous_mode);
	test_proxy(proxy_settings::socks5_pw, anonymous_mode);
	test_proxy(proxy_settings::http, anonymous_mode | expect_udp_reject);
	test_proxy(proxy_settings::http_pw, anonymous_mode | expect_udp_reject);
	test_proxy(proxy_settings::i2p_proxy, anonymous_mode);
	return 0;
}

<|endoftext|>


<commit_before>#include "PrimeSieve.h"
#include <cassert>
#include <climits>
#include <ctime>
#include <iostream>
#include <list>
#include <utility>
#include <vector>
using namespace std;

static void AssertPrime(int k) {
  int mod_count = 0;
  int sqrt_k = (int)sqrt((double)k);
  for (int i = 2; i <= sqrt_k; i++) {
    assert(k % i != 0);
  }
}

void TestSmall() {
  int n = 100000;
  BitVec *b = SimpleSieve(n);
  for (int i = 2; i < n; i++) {
    if (IsPrime(b, i)) {
      AssertPrime(i);
    }
  }
}

void TestBig() {
  int n = INT_MAX / 10;

  time_t beg, end;
  std::cerr << "Big Test on: " << n << std::endl;
  beg = std::time(0);
  std::cerr << "SimpleSieve start at: " << beg << std::endl;
  BitVec *ss = SimpleSieve(n);
  end = std::time(0);
  std::cerr << "SimpleSieve end at: " << end << std::endl;
  std::cerr << "SimpleSieve used: " << (end - beg) << " seconds" << std::endl;

  std::cerr << "EratosthenesSieve on: " << n << std::endl;
  beg = std::time(0);
  std::cerr << "EratosthenesSieve start at: " << beg << std::endl;
  BitVec *es = EratosthenesSieve(n);
  end = std::time(0);
  std::cerr << "EratosthenesSieve end at: " << end << std::endl;
  std::cerr << "EratosthenesSieve used: " << (end - beg) << " seconds"
            << std::endl;
  for (int i = 2; i < n; i++) {
    assert(IsPrime(ss, i) == IsPrime(es, i));
  }
  BitVecFree(ss);
  BitVecFree(es);
}

int main(void) {
  TestSmall();
  TestBig();
  return 0;
}

<commit_msg>add cmath header<commit_after>#include "PrimeSieve.h"
#include <cassert>
#include <climits>
#include <cmath>
#include <ctime>
#include <iostream>
#include <list>
#include <utility>
#include <vector>
using namespace std;

static void AssertPrime(int k) {
  int mod_count = 0;
  int sqrt_k = (int)sqrt((double)k);
  for (int i = 2; i <= sqrt_k; i++) {
    assert(k % i != 0);
  }
}

void TestSmall() {
  int n = 100000;
  BitVec *b = SimpleSieve(n);
  for (int i = 2; i < n; i++) {
    if (IsPrime(b, i)) {
      AssertPrime(i);
    }
  }
}

void TestBig() {
  int n = INT_MAX / 10;

  time_t beg, end;
  std::cerr << "Big Test on: " << n << std::endl;
  beg = std::time(0);
  std::cerr << "SimpleSieve start at: " << beg << std::endl;
  BitVec *ss = SimpleSieve(n);
  end = std::time(0);
  std::cerr << "SimpleSieve end at: " << end << std::endl;
  std::cerr << "SimpleSieve used: " << (end - beg) << " seconds" << std::endl;

  std::cerr << "EratosthenesSieve on: " << n << std::endl;
  beg = std::time(0);
  std::cerr << "EratosthenesSieve start at: " << beg << std::endl;
  BitVec *es = EratosthenesSieve(n);
  end = std::time(0);
  std::cerr << "EratosthenesSieve end at: " << end << std::endl;
  std::cerr << "EratosthenesSieve used: " << (end - beg) << " seconds"
            << std::endl;
  for (int i = 2; i < n; i++) {
    assert(IsPrime(ss, i) == IsPrime(es, i));
  }
  BitVecFree(ss);
  BitVecFree(es);
}

int main(void) {
  TestSmall();
  TestBig();
  return 0;
}

<|endoftext|>


<commit_before>#include <gtest/gtest.h>

#include <sauce/sauce.h>

namespace sauce {
namespace test {

/**
 * This suite is intended to be a complete (if stubbed) example of how sauce might be used to manage the dependencies
 * of a typical MVC-like application.  Unlike binding_test, whose aim is coverage across all variations of binding and
 * use, the focus here is on clarity and documentation.
 *
 * Suppose we are creating a web application allowing a Mom & Pop pizza parlour to accept orders online.  Customers can
 * choose toppings, sauce (ha!) and crust, specify take-out or delivery (giving an address as needed) and later inspect
 * the progress of their order.  An employee at the store uses a similar interface to declare when an order has
 * started, left for delivery, etc.  This application runs in a three-tier architecture of a web server backed by app
 * processes talking to a single relational database.
 *
 * Even in this simple application there is complexity to manage, which can be addressed by following the MVC pattern.
 * Vanilla MVC articulates a useful separation of concerns and wraps each in an object.  However it is silent about how
 * those objects are ultimately assembled into the final application; this is where dependency injection (and sauce)
 * can help.
 *
 * Since the point of the technique is to keep components decoupled and unaware of each other, a real application would
 * likely spread its components out across many headers and compilation units.  This poses no problem for sauce, but
 * for clarity everything in this example is contained in this suite.  Comments indicate where suggested file breaks
 * might occur.
 */

// ********************************************************************************************************************
// orm.h

/**
 * This is not part of the pizza application proper, but is a library used by the application author to manage access
 * to the database.  It does so by materializing rows as application objects in memory, hiding details (like SQL) from
 * the application author.
 */

// ********************************************************************************************************************
// routes.h

/**
 * This too is a library used by the application author, now to declare how incoming requests are mapped to the
 * controllers that serve them.
 */

// ********************************************************************************************************************
// clock.h

/**
 * This library just exposes the local clock, allowing the application author to sample timestamps.
 */

// ********************************************************************************************************************
// order_model.h

/**
 * A pizza order being processed.
 */

// ********************************************************************************************************************
// place_controller.h

/**
 * Handles requests to place an order.
 */

// ********************************************************************************************************************
// status_controller.h

/**
 * Handles requests regarding an order's status.
 */

// ********************************************************************************************************************
// place_controller_test.cc

/**
 * The unit test suite for PlaceController, demonstrating how to inject mocks or stubs.
 */

// ********************************************************************************************************************
// production_module.cc

/**
 * The sauce module, written by the application author, that specifies the bindings used when running in production.
 */

// ********************************************************************************************************************
// main.cc

/**
 * The entry point of the application, and where sauce injects dependencies.
 */
TEST(TutorialTest, main) { // Let's pretend this is main()
  ASSERT_TRUE(true);
}

}
}
<commit_msg>More tutorial.<commit_after>#include <gtest/gtest.h>

#include <sauce/sauce.h>

namespace sauce_tutorial { // Put in a different namespace, forcing us to show off "using" statements.
namespace test {

/**
 * This suite is intended to be a complete (if stubbed) example of how sauce might be used to manage the dependencies
 * of a typical MVC-like application.  Unlike binding_test, whose aim is coverage across all variations of binding and
 * use, the focus here is on clarity and documentation.
 *
 * Suppose we are creating a web application allowing a Mom & Pop pizza parlour to accept orders online.  Customers can
 * choose toppings, sauce (ha!) and crust, specify take-out or delivery (giving an address as needed) and later inspect
 * the progress of their order.  An employee at the store uses a similar interface to declare when an order has
 * started, left for delivery, etc.  This application runs in a three-tier architecture of a web server backed by app
 * processes talking to a single relational database.
 *
 * Even in this simple application there is complexity to manage, which can be addressed by following the MVC pattern.
 * Vanilla MVC articulates a useful separation of concerns and wraps each in an object.  However it is silent about how
 * those objects are ultimately assembled into the final application; this is where dependency injection (and sauce)
 * can help.
 *
 * Since the point of the technique is to keep components decoupled and unaware of each other, a real application would
 * likely spread its components out across many headers and compilation units.  This poses no problem for sauce, but
 * for clarity everything in this example is contained in this suite.  Comments indicate where suggested file breaks
 * might occur.
 */

// ********************************************************************************************************************
// orm.h

/**
 * This is not part of the pizza application proper, but is a library used by the application author to manage access
 * to the database.  It does so by materializing rows as application objects in memory, hiding details (like SQL) from
 * the application author.
 */

// ********************************************************************************************************************
// web.h

/**
 * This too is a library used by the application author, now to declare how incoming requests are mapped to the
 * controllers that serve them.
 */

// ********************************************************************************************************************
// clock.h

/**
 * This library just exposes the local clock, allowing the application author to sample timestamps.
 *
 * Mocking a clock for testing is a typical chore for temporal code; we will demonstrate doing this with sauce below.
 */

// Seconds since the epoch.
typedef int Timestamp;

/**
 * The clock interface.
 *
 * Typically this (and an adapter for the system clock) is supplied by the application or framework author.
 */
struct Clock {
  virtual Timestamp timestamp() = 0;
};

/**
 * "Real" clock implementation.
 *
 * Returned timestamps are taken from a counter that is bumped on each call to suggest an actual clock.
 */
struct SystemClock: public Clock {
  Timestamp currentTime;

  SystemClock():
    currentTime(0) {}

  Timestamp timestamp() {
    return currentTime++;
  }
};

// ********************************************************************************************************************
// order_model.h

/**
 * A pizza order being processed.
 */

// ********************************************************************************************************************
// routes.h

/**
 * Mappings between url patterns and controllers, supplied by the application author, in our ficticuous framework.
 */

// ********************************************************************************************************************
// place_controller.h

/**
 * Handles requests to place an order.
 */

// ********************************************************************************************************************
// status_controller.h

/**
 * Handles requests regarding an order's status.
 */

// ********************************************************************************************************************
// place_controller_test.cc

/**
 * The unit test suite for PlaceController, demonstrating how to inject mocks or stubs.
 */

using sauce::Binder;

struct StubClock: public Clock {
  Timestamp timestamp() {
    return 0;
  }
};

/**
 * The sauce module, written by the application author, that specifies bindings for this unit test suite.
 *
 * Modules are collections of bindings, which tell sauce how interface requests should be satisfied.  The application
 * author tells sauce about bindings with a "fluent" API exposed either by the passed Binder or inherited from
 * AbstractModule (see below.)
 *
 * Each binding begins with a call to bind, passing the interface to be bound as a template parameter.  Further chained
 * calls declare what concrete implementation should be used, and customize how to make or find it.
 */
void MockModule(Binder & binder) {
  /**
   * The result of bind() (an intermediate with an annoyingly complex type) is invoked in turn.
   *
   * Here, to<StubClock()>() says that requests for the interface Clock should be satisfied with instances of the
   * StubClock concrete type.
   *
   * StubClock() is actually a function type.  This is how we specify which constructor to use.  If the chosen
   * constructor takes arguments, they are treated as dependencies and satisfied first.
   */
  binder.bind<Clock>().to<StubClock()>();
}

// ********************************************************************************************************************
// production_module.cc

using sauce::AbstractModule;

/**
 * The sauce module, written by the application author, that specifies the bindings used when running in production.
 *
 * Concretely, a module is either a void (Binder &) function as above, or a class deriving from AbstractModule as is
 * the case here. (Technically any type providing a void operator()(Binder & binder) will do.)
 *
 * The difference is just sugar: the AbstractModule doesn't need to prefix bindings with "binder." while the function
 * is conceptually simpler and more concrete.
 */
class ProductionModule: public AbstractModule {
  void configure() {
    // Here there is no Binder, we just call bind<Iface>() directly.
    bind<Clock>().to<SystemClock()>();
  }
};

// ********************************************************************************************************************
// main.cc

using sauce::Modules;
using sauce::Injector;

/**
 * The entry point of the application, and where sauce injects dependencies.
 */
TEST(TutorialTest, main) { // Let's pretend this is main()
  /**
   * Create an injector by first choosing what modules to use.  These are accumulated in a Modules object.
   * More than one module can be selected, allowing the application developer to mix and match.
   */
  Modules modules;
  modules.add(ProductionModule());

  /**
   * After desired modules are added, use createInjector() to get an injector itself.  It is returned as a
   * sauce::shared_ptr, which is just an alias for std::shared_ptr (though std::tr1 and boost smart pointers can be
   * used, if the SAUCE_STD_TR1_SMART_PTR or SAUCE_BOOST_SMART_PTR preprocessor symbols are defined.)
   *
   */
  sauce::shared_ptr<Injector> injector = modules.createInjector();

  ASSERT_TRUE(true);
}

}
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <data.h>
#include <constants.h>
#include <initialconditions.h>
#include <mesh.h>
#include <omp.h>

using namespace std;

extern vector<element> e;

double uinf, vinf, roinf, Tinf, muinf, Reinf, pinf, Machinf, hinf, Vinf, ainf;

void readbackup()
{
  if(fileExists("mesh/backup.txt"))
    {

      cout << "Backup found." << endl;
    }
  else
    {
      cout << "Backup not found." << endl;

      cin.get();
    }

  fstream read ("mesh/backup.txt");

  double p, T, u, v;

  int i = 1;

  while(read >> u >> v >> p >> T)
    {
      e[i].u = u / Vinf;
      e[i].v = v / Vinf;
      e[i].p = p / (roinf * pow(Vinf, 2));
      e[i].T = T / Tinf;

      e[i].ro = e[i].p * (roinf * pow(Vinf, 2)) / (R * e[i].T * Tinf * roinf);

      e[i].mu = (1.461e-6 * pow(e[i].T * Tinf, (3. / 2.)) / (e[i].T * Tinf + 110.3)) / muinf;

      e[i].V = sqrt(pow(e[i].u, 2) + pow(e[i].v, 2));
      e[i].et = (cv * e[i].T * Tinf + pow(e[i].V * Vinf, 2) / 2.) / pow(Vinf, 2);

      i++;
    }

}

void initialconditions()
{
  string line;

  fstream read("mesh/initialconditions.txt");

  getline(read,line,':');

  read >> uinf;

  getline(read,line,':');

  read >> vinf;

  getline(read,line,':');

  read >> pinf;

  getline(read,line,':');

  read >> Tinf;

  Vinf = sqrt(pow(uinf, 2) + pow(vinf, 2));

  ainf = sqrt(gama * R * Tinf);

  muinf = 1.461e-6 * pow(Tinf, (3. / 2.)) / (Tinf + 110.3);

  roinf = pinf / (R * Tinf);

  Reinf = roinf * Vinf / muinf;

  Machinf = Vinf / ainf;

  //hinf = (gama * cv * Tinf + 1. / 2. * (pow(uinf, 2) + pow(vinf, 2))) / pow(uinf,2) ;

  if(readbackupflag == 1)
    readbackup();

  else
    {
#pragma omp parallel for schedule(dynamic,1000)
      for(unsigned int i = 1; i < e.size(); i++)
        {
          e[i].u = uinf / Vinf;
          e[i].v = vinf / Vinf;

          e[i].ro = roinf / roinf;
          e[i].T = Tinf / Tinf;
          e[i].mu = muinf / muinf;

          e[i].V = sqrt(pow(e[i].u, 2) + pow(e[i].v, 2));
          e[i].et = (cv * e[i].T * Tinf + pow(e[i].V * Vinf, 2) / 2.) / pow(Vinf, 2);
          e[i].p = pinf / (roinf * pow(Vinf, 2));

          e[i].unew = e[i].u;
          e[i].vnew =  e[i].v;

          e[i].ronew = e[i].ro;
          e[i].Tnew = e[i].T;
          e[i].munew = e[i].mu;

          e[i].Vnew = e[i].V;
          e[i].etnew = e[i].et;
          e[i].pnew = e[i].p;
        }

#pragma omp parallel for schedule(dynamic,1000)
      for(unsigned int i = 1; i < e.size(); i++)
        {
              e[i].u = Vinf / Vinf;
              e[i].v = 0. / Vinf;

              e[i].ro = roinf / roinf;
              e[i].T = Tinf / Tinf;
              e[i].mu = muinf / muinf;

              e[i].V = sqrt(pow(e[i].u, 2) + pow(e[i].v, 2));
              e[i].et = (cv * e[i].T * Tinf + pow(e[i].V * Vinf, 2) / 2.) / pow(Vinf, 2);
              e[i].p = e[i].ro * roinf * R * e[i].T * Tinf / (roinf * pow(Vinf, 2));

              e[i].unew = e[i].u;
              e[i].vnew =  e[i].v;

              e[i].ronew = e[i].ro;
              e[i].Tnew = e[i].T;
              e[i].munew = e[i].mu;

              e[i].Vnew = e[i].V;
              e[i].etnew = e[i].et;
              e[i].pnew = e[i].p;

        }

    }

}

<commit_msg>Delete initialconditions.cpp<commit_after><|endoftext|>