bool DataSetValues::SetDataSet(DataSet *ds)
{
   if (ds && !ds->GetReadable())
   {
      LogError2(GetType()->GetLogCategory(), GetName(),tr("Data Set Values Display can't be set to a data set that is not readable."));
      return false;
   }

   if (m_dataSet)
   {
      disconnect(m_dataSet,SIGNAL(BeforeDeletion(DataClass*)),this,SLOT(OnBeforeDataSetRemovedSlot(DataClass*)));
      disconnect(m_dataSet,SIGNAL(InputSourceAssigned(DataSet*)),this,SLOT(OnDataSetSourceSet(DataSet*)));
      disconnect(m_dataSet,SIGNAL(NewData(DataClass*)),this,SLOT(OnNewData(DataClass*)));
      disconnect(m_dataSet,SIGNAL(StructureChanged(DataSource*)),this,SLOT(OnDataSetSourceStructureChanged(DataSource*)));
      disconnect(m_dataSet,SIGNAL(NameChanged(DataClass*)),this,SLOT(OnDataSetNameChanged(DataClass*)));
   }
   m_dataSet = ds;
   if (m_dataSet)
   {
      connect(m_dataSet,SIGNAL(BeforeDeletion(DataClass*)),this,SLOT(OnBeforeDataSetRemovedSlot(DataClass*)));
      connect(m_dataSet,SIGNAL(InputSourceAssigned(DataSet*)),this,SLOT(OnDataSetSourceSet(DataSet*)));
      connect(m_dataSet,SIGNAL(NewData(DataClass*)),this,SLOT(OnNewData(DataClass*)));
      connect(m_dataSet,SIGNAL(StructureChanged(DataSource*)),this,SLOT(OnDataSetSourceStructureChanged(DataSource*)));
      connect(m_dataSet,SIGNAL(NameChanged(DataClass*)),this,SLOT(OnDataSetNameChanged(DataClass*)));

      m_dataType = ds->GetDataType();
      m_firstVisibleElement = ds->GetFirstIndex();
      OnDataSetNameChanged(m_dataSet);
   }

   ParametersUpdated();
   return true;
}
Beispiel #2
0
void CPage::LoadCache(ConnectionPtr connection)
{
	Trace("LoadCache", "",0);

    ResultPtr result;
	ncc::safe_array<char> strQuery(10240);

	try
	{
		// load from the database
		snprintf(strQuery, strQuery.size(), SQL_WTT_LOAD_CACHE, m_runID);

		Trace("Query for LoadCache", strQuery, 0);
		result = connection->Query(strQuery);

		while(result->Next())
		{
			RowPtr row = result->GetCurrentRow();
			// add it
			std::string urlStr;
			urlStr = row->GetFieldString(1);
			{ // scope for lock
				Mutex::Lock lock(sm_urlListLock);
				m_totalUrlList.push_back(urlStr);
			}
		}
	}
	catch (const std::exception& e)
	{
		LogError2("LoadCache() - Caught Exception", e.what(), 0, SC_ERR_GROUP_DB, SC_ERR_CODE_LOAD_CACHE);
	}
}
Beispiel #3
0
void CPage::SaveCache(ConnectionPtr connection)
{
	Trace("SaveCache", "", m_totalUrlList.size());

	// save all the cookies in the current memory list to the database
	// in the WebPageCookies table
	ncc::safe_array<char> strQuery(102400);
	ncc::safe_array<char> sqlCache(40961);

	{ // scope for lock
		// delete the existing cache in the table for this run
		snprintf(strQuery, strQuery.size(), SQL_WTT_DEL_CACHE, m_runID);

		Trace("Query for SaveCache", strQuery, 0);
		 connection->Query(strQuery);

		try
		{
			for (URLList::const_iterator it = m_totalUrlList.begin(); it != m_totalUrlList.end(); ++it)
			{
				// convert the string ready to be inserted
				int len = 0;
				// convert the string for inserting
				len = mysql_escape_string(sqlCache, (*it).c_str(),((*it).size()<40960)?((*it).size()):40960);

				// terminate the string
				if( len > 40960)
				{
					sqlCache[40960] = '\0';
				}
				else
				{
					sqlCache[len] = '\0';
				}

				// make sure last char not a \ - it would escape the final quote
				if( sqlCache[40959] == '\\')
				{
					sqlCache[40959] = ' ';
				}
				else  if( sqlCache[len-1] == '\\')
				{
					sqlCache[len-1] = ' ';
				}

				// save to the database
				snprintf(strQuery, strQuery.size(), SQL_WTT_SAVE_CACHE, m_runID, static_cast<const char*>(sqlCache));

				Trace("Query for SaveCache", strQuery, 0);
				connection->Query(strQuery);
			}
		}
		catch (const std::exception& e)
		{
			LogError2("SaveCache() - Caught Exception", e.what(), 0, SC_ERR_GROUP_DB, SC_ERR_CODE_STORE_CACHE);
		}
	}
}
Beispiel #4
0
ConnectionPtr CPage::getDbConnection()
{
	// if not already connected - create one
	if (sm_pDbConnection.get() == NULL)
	{
		sm_pDbConnection.reset(
			new Connection(
					CConfig::getDBServer(),
					CConfig::getDBDatabase(),
					CConfig::getDBUser(),
					CConfig::getDBPass(),
					CConfig::getDBRetryTime()));
	}

	if (sm_pDbConnection.get() == NULL)
	{
		LogError2("CPage::getDbConnection()", "Unable to create new Connection", 0,
				SC_ERR_GROUP_AGENT, SC_ERR_CODE_UNABLE_TO_CREATE_TCP_CONN);
	}

	return sm_pDbConnection;
}
Beispiel #5
0
resultid_t runWTTI(const char* url, std::string& dbName, unsigned int wttiRunID, unsigned int shardNumber, int webkitTimeout)
{
	std::string strQuery;
	sem_init( &(CWebPage::Instance()->sm_hostSemaphore), 0, 0 );
	sem_init( &(CWebPage::Instance()->sm_threadControlSemaphore), 0, 0 );

#ifdef SHARD_AWARE
	ConnectionPtr connection(
		new Connection(
			CConfig::getShardServer(shardNumber),
			CConfig::getShardDatabase(shardNumber),
			CConfig::getShardUser(shardNumber),
			CConfig::getShardPass(shardNumber),
			CConfig::getDBRetryTime()));
#else
	ConnectionPtr connection(
		new Connection(
			CConfig::getDBServer(),
			CConfig::getDBDatabase(),
			CConfig::getDBUser(),
			CConfig::getDBPass(),
			CConfig::getDBRetryTime()));
#endif

	std::string urlToTest;

	// Get URL from the WttiTests table.
	ResultPtr resultUrl;
	strQuery = Format(SQL_WTTI_SELECT_URL, wttiRunID);
	resultUrl = connection->Query(strQuery.c_str());
	if ( resultUrl->Next() )
	{
		RowPtr row = resultUrl->GetCurrentRow();
		urlToTest = row->GetFieldString(1);

		Trace("Rows:", "", resultUrl->GetRowCount());
	}

	resultid_t dailyResultID = 0;
	PackDiagStorage store;

	int pageID = 0;
	CResultSet resultSet;
	CTcp* pTcpConnection = new CTcp("", 0);

	// Turn CSS Parsing on permanently.
	CWebPage::Instance()->sm_doCssParsing = 1;
    
    //Turn SSL validation on permanently
    CWebPage::Instance()->sm_doSslValidation = 1;
    CTcp::setDoSslValidation(1);

	// create the new web page object
	CWebPage* pPage = new CWebPage(
		resultSet,
		pTcpConnection,
		0,
		SC_SERVICE_BENCHMARK,
		urlToTest, // url
		pageID, // page id
		SC_WEBPAGE_TYPE_IMED, // page type
		true, // reset cookies
		std::string(), // auth user
		std::string(), // auth pass
		DOWNLOAD_THRESHOLD_SECS, // download threshold
		true, // reset cache
		CConfig::getServerID(),
		SC_WEBPAGE_STATUS_OK, // bodge to be status live page
		HTTP_METHOD_GET, // bodge to get GET by default
		std::string(),
		std::vector<std::string>(),
		std::vector<char>(), // emptyVector,    // bodge - no form variables
		std::string() // fileStr  // bodge - no file variables
		);

	// reset the counters
	pPage->resetPage();

	// record when we started the test
	//pPage->setStartTime();

	// make sure we don't report a hacking / login failure
	// pPage->phraseWasFound();
	// Set that a connection exists to this host.
	//pPage->isHostConnectionsExceeded(static_cast<std::string>(url));
	// do the load of this page
	//pPage->load();

	// add the page just loaded to the list of those done so it doesn't get done again
	// via a redirect
	//CWebPage::AddURLDone(url);

	// reset the first byte count for the page
	//pPage->resetSpeedCounters();

	MultiThreadSetup();

	// ----------------------
	// --- THREAD MANAGER ---
	// ----------------------
	std::string protoAndHost;
	protoAndHost = urlToTest;

	// Calculate protocol type.
	if (strncasecmp (protoAndHost.c_str(), "http://", 7) == 0)
	{
		std::string::size_type hostLength = protoAndHost.find("/", 7);
		if (hostLength != std::string::npos)
			protoAndHost = protoAndHost.substr(0, hostLength);
	}
	else if (strncasecmp (protoAndHost.c_str(), "https://", 8) == 0)
	{
		std::string::size_type hostLength = protoAndHost.find("/", 8);
		if (hostLength != std::string::npos)
			protoAndHost = protoAndHost.substr(0, hostLength);
	}
	else
	{
		std::string::size_type hostLength = protoAndHost.find("/");
		if (hostLength != std::string::npos)
			protoAndHost = "http://" + protoAndHost.substr(0, hostLength);
		else
			protoAndHost = protoAndHost.insert(0, "http://");
	}


	// Add the host that we're about to connect to so it does not get added again.
	{
		Mutex::Lock lock(CWebPage::Instance()->sm_connectedHostsLock);
		CWebPage::Instance()->sm_connectedHosts.push_back(std::make_pair(true, protoAndHost));
	}


	std::vector<ThreadArgs*> threadArgsVector;

	// JYLS WEBKIT START

#ifndef SC_NON_WEBKIT
#ifdef SC_WEBKIT_V89

	curlwrapper_init(pPage, startThread);

	//Use the default value from the opt file for these
	ww_setMaxNumberOfThreadsPerHost(CConfig::getDefaultMaxThreadsPerHost());
	ww_setMaxTotalNumberOfThreads(CConfig::getDefaultMaxTotalThreads());
	ww_setScreenXDimension(CConfig::getScreenXDimension());
	ww_setScreenYDimension(CConfig::getScreenYDimension());
	ww_setJavascriptTimeout(CConfig::getJsExecutionTimeout());

	ww_loadPageByWebkit(pPage->getURL().c_str(), true, DOWNLOAD_THRESHOLD_SECS, webkitTimeout);

#else
	bool isJavascriptEnabled = true;

	soupwrapper_init(pPage, startThread);

	ww_setPageId(pageID);
	ww_setWebkitTimeout(webkitTimeout);
	ww_setWebkitTimeoutHard(CConfig::getWebkitHardTimeout());

	load_page_by_webkit(pPage->getURL(), isJavascriptEnabled);
#endif	// SC_WEBKIT_V89
#else
	std::vector<pthread_t> threadIds;
	pthread_t threadId;
	int res = 0;
	unsigned int maxThreadsPerHost = 0;

	if (maxThreadsPerHost == 0)
		maxThreadsPerHost = CConfig::getDefaultMaxThreadsPerHost();

	//Limit the value of maxThreadsPerHost
	if (maxThreadsPerHost > CConfig::getMaxThreadsPerHostLimit())
		maxThreadsPerHost = CConfig::getMaxThreadsPerHostLimit();

	unsigned int numThreads = maxThreadsPerHost;

	for (unsigned int a = 0; a < numThreads; ++a)
	{
		ThreadArgs* args1 = new ThreadArgs;
		args1->isFirstPage = (a == 0);
		args1->pPage       = pPage;
		args1->host        = protoAndHost;
		res = pthread_create(&(threadId), NULL, startThread, (void*)args1);
		if ( res != 0 )
		{
			LogError("Failed to start thread for", protoAndHost.c_str(), 0);
		}
		else
		{
			threadIds.push_back(threadId);
			threadArgsVector.push_back(args1);

			// Wait for the second thread to signal it has started.
			sem_wait(&(CWebPage::Instance()->sm_threadControlSemaphore));
		}
	}

	std::vector<CWebPage::HostPair>::const_iterator hostIt;

	Trace("before starting threads", "", 0);

	while ((CWebPage::getUrlListSize()) > 0 || (CWebPage::Instance()->sm_numWorkingThreads > 0))
	{
		{
			Mutex::Lock lock(CWebPage::Instance()->sm_connectedHostsLock);
			for ( hostIt = CWebPage::Instance()->sm_connectedHosts.begin(); hostIt != CWebPage::Instance()->sm_connectedHosts.end(); ++hostIt )
			{
				if ( !(hostIt->first) )
				{
					unsigned int numThreads = maxThreadsPerHost;

					for (unsigned int a = 0; a < numThreads; ++a)
					{
						bool errorOccured = false;
						std::string hostToConnect;
						hostToConnect.assign(hostIt->second);

						// Start threads per new host encountered.
						Trace("Starting threads for", hostIt->second.c_str(), 0);

						ThreadArgs* args2  = new ThreadArgs;
						args2->isFirstPage = false;
						args2->pPage       = pPage;
						args2->host        = hostToConnect;

						res = pthread_create(&(threadId), NULL, startThread, (void*)args2);
						if ( res != 0 )
						{
							LogError("Failed to start thread for", hostIt->second.c_str(), 2);
							errorOccured = true;
						}
						else
						{
							threadIds.push_back(threadId);
							threadArgsVector.push_back(args2);
							// Wait for thread to start.
							sem_wait(&(CWebPage::Instance()->sm_threadControlSemaphore));
						}

						// Connected ok.
						hostIt->first = true;
					}
				}
			}
		}

		// Wait for more hosts to be encountered.
		sem_wait(&(CWebPage::Instance()->sm_hostSemaphore));
	}

#endif	// SC_NON_WEBKIT
	// JYLS WEBKIT END

	Trace("Deleting semaphore", "", 0);
	sem_destroy(&(CWebPage::Instance()->sm_hostSemaphore));
	sem_destroy(&(CWebPage::Instance()->sm_threadControlSemaphore));
#ifdef SC_NON_WEBKIT
	// Write debug information if components remain.
	if (CWebPage::getUrlListSize() > 0)
	{
		CWebPage::writeThreadsDebug();

		int count = 0;
		std::vector<ThreadArgs*>::const_iterator threadsIt;
		for (threadsIt = threadArgsVector.begin(); threadsIt != threadArgsVector.end(); ++threadsIt)
		{
			LogInfo("Threads started=", (*threadsIt)->host.c_str(), count);
			++count;
		}
	}
#endif	// SC_NON_WEBKIT

#ifndef SC_NON_WEBKIT
	// Sleep to allow for extra components from eg javascript
	usleep(1000000);

	//Actually check how many threads are running, go ahead if 0
	while (CWebPage::Instance()->sm_numWorkingThreads)
	{
		usleep(10000);
	}
#else
	void* threadResult;

	// Join started threads.
	for (unsigned int i = 0; i < threadIds.size(); ++i)
	{
		res = pthread_join(threadIds[i], &threadResult);
		if (res != 0)
		{
			LogError("Unable to join thread", "", res);
		}
		else
		{
			Trace("Joined thread", "", res);
		}
	}
#endif	// SC_NON_WEBKIT

	// Delete all ThreadArgs used.
	while ( !threadArgsVector.empty() )
	{
		delete threadArgsVector.back();
		threadArgsVector.pop_back();
	}

	setResultCode(pPage, CWebPage::Instance()->sm_firstPageResultCode);

	try
	{
		Trace("Connecting to db", "", 0);

		std::string requestStr;
		std::string headerStr;
		std::string htmlStr;
		std::string extraInfoStr;

		// extra info for ResultHeader
		if (!resultSet.getResultDetails().empty())
		{
			const CResultDetail* pResultDetail = resultSet.getFirstResultDetail();

			requestStr = pResultDetail->getRequest();
			headerStr = pResultDetail->getHeaders();
			htmlStr = pResultDetail->getPageText();
			extraInfoStr = pResultDetail->getExtraInfo();
		}

		const bool pageInError = pPage->getOverallResultCode() != SC_HEADER_RESULT_SUCCESS && pPage->getOverallResultCode() != SC_HEADER_RESULT_DUMMY_TRANSACTION;

		// 3.0.0 Daily ResultHeader tables
		StoreHeaderDaily(
			connection,
			resultSet,
			pPage->getPageID(),
			CConfig::getServerID(),
			pPage->getStartTimeStr(),
			pPage->getOverallResultCode(),
			pPage->getDNSTimeOffsetMs(),
			pPage->getConnectTimeOffsetMs(),
			pPage->getTotalLastByteTimeOffsetMs(),
			pPage->getTotalBytes(),
			&dailyResultID,
			pPage->getFirstDataTimeOffsetMs(),
			pPage->getDailyTableName(),
			PackDiagOverride(),
			store,
			pageInError,
			false,
			SC_TEST_TYPE_WTTI,
			0,
			0,
			0,
			CSCGlobal::gAgentVersion,
			pPage->getTotalGzipBytes(),
			false, //diagstored
			pPage->getSslConnectTimeOffsetMs(),
			pPage->getRequestSentTimeOffsetMs(),
			pPage->getRequestHeaderSize(),
			pPage->getRequestContentSize(),
			pPage->getResponseHeaderSize());

		// now store all the detail - always do this for wtti
		int ComponentNo = 1;
		for (CResultSet::ResultList::const_iterator p = resultSet.getResultDetails().begin(); p != resultSet.getResultDetails().end(); ++p, ++ComponentNo)
		{
			// now go and get the rest of the files - with threads
			if (const CResultDetail* pResultDetail = p->pResultDetail)
			{
				pResultDetail->setComponentNo(ComponentNo);

				// 3.0.0 Daily ResultDetail tables
				StoreResultDaily(
					connection,
					resultSet,
					ComponentNo,
					pResultDetail,
					dailyResultID,
					pPage->getDailyTableName());
			}
		}
	}
	catch (const std::exception &e)
	{
		Trace("Exception caught", e.what(), 0);
		LogError2("Exception Caught:", e.what(), 0, SC_ERR_GROUP_AGENT, SC_ERR_CODE_WTTI);
		return 0;
	}
	
#ifdef SHARD_AWARE
	// Write the result ID back to the transient table so the website can pick it up.
	strQuery = Format(SQL_WTTI_INSERT_RESULTID, dailyResultID, wttiRunID);
	Trace("Issuing query", strQuery.c_str(), dailyResultID);
	connection->Query(strQuery);
#endif

	//
	dbName = pPage->getDailyTableName();

	// complete it
	delete pPage;
	pPage = NULL;

	MultiThreadCleanup();

	// Remove /tmp/session_id.<pid>p.host files
	long int uniqueId = getpid();
	std::string identifier = WTTP_SESSION_ID_IDENTIFIER;
	strQuery = Format("rm -f /tmp/session_id.%ld%s.*", uniqueId, identifier.c_str());
	int ret = system(strQuery.c_str());
	Trace("System call returned", strQuery.c_str(), ret);

	return dailyResultID;
}