示例#1
0
/*! \brief Detect excessive disk usage by the test and turn all further logging off if more than a specific limit number of mebibytes has been used.

When called, this function will check the amount of space used on the generator's "output" device / directory since the first call to this function.
If the amount of used space exceeds the treshold it will generate an error transaction "---DISK SPACE LOW IN LOG FOLDER FOR {y_hostname_generator}---" and turn all further logging off until the end of the test, using y_log_turn_off_permanently().

\note Scripts that call lr_debug_message() or the various y_lib() toggle functions to turn the loglevel back up may ignore this restriction.

Loadrunner does not protect the generators' disks from overflowing, even if the test is writing out a lot of information to the logs really quickly.
If a disk fills up on the generator or the disk the controller uses for results collation overflows there is no graceful recovery. Collation will fail and test results may be hard or impossible to recover.
This kind of situation can occur when temporary service disruptions happen (triggering a flood of 'log on error' messages), but also if runtime settings are incorrect and the test was configured to log *everything*.

\note Because of the way this measurement is done, it may also trigger if some other process on the same machine starts writing large amounts of data to the same device.

In order to prevent this from happening scripts should regularly call to both y_disk_space_guard() and y_disk_space_usage_guard() with some reasonable limits.

\note The contents of the generator's output folder will be transferred to the controller during collation. If the sum of the output directories for the generators exceed the size of that filesystem collation will fail, even if there is enough space on the generators. Therefore, set this low enough to make sure that if all generators output folders get filled to the limit the controller will still have enough space for it's collation process.

\param [in] limit_mebibytes_used The amount of mebibytes the test is allowed to used on the generator's target directory. 

\author Floris Kraak
*/
void y_disk_space_usage_guard(double limit_mebibytes_used)
{
    char* hostname;
    char* log_folder = lr_get_attrib_string("out");
    double free_mebibytes;
    static double max_free_mebibytes = -1;
    double mebibytes_used;
    static int disk_space_warning_given = 0;

    // check already fired once before.
    if( disk_space_warning_given )
    {
        // guard against accidental re-enablement of the logs by turning them off explicitly.
        y_log_turn_off_permanently();
        return;
    }

    free_mebibytes = y_get_free_disk_space_in_mebibytes(log_folder);
    lr_log_message("y_disk_space_usage_guard: current free: %f MB, max free: %f MB, limit: %f MB used in folder: %s",
                   free_mebibytes, max_free_mebibytes, limit_mebibytes_used, log_folder);

    if(max_free_mebibytes < 0)
    {
        lr_log_message("Storing free space as detected maximum");
        max_free_mebibytes = free_mebibytes;
        return;
    }
    else if(max_free_mebibytes < free_mebibytes)
    {
        lr_output_message("Warning: Free disk space increased from %f to %f, test disk space usage measurements may have become unreliable.", max_free_mebibytes, free_mebibytes);
        max_free_mebibytes = free_mebibytes;
        return;
    }

    // Ok, so we used *something*. Now let's see if it exceeds our limit.
    mebibytes_used = max_free_mebibytes - free_mebibytes;

    // data points
    hostname = lr_get_host_name();
    lr_save_string(hostname, "y_hostname_generator");
    lr_user_data_point( lr_eval_string("disk_space_{y_hostname_generator}_free_mebibytes"), free_mebibytes);
    lr_user_data_point( lr_eval_string("disk_space_{y_hostname_generator}_used_mebibytes"), mebibytes_used);

    if( mebibytes_used >= limit_mebibytes_used ) 
    {
        y_setup();
        lr_set_transaction(lr_eval_string("---DISKSPACE USAGE TOO HIGH IN LOG FOLDER FOR {y_hostname_generator}---"), 0, LR_FAIL);
        lr_output_message("Disk space used on host %s in folder %s was %f mebibytes, reaching the limit of %f. Logging turned off for user id %d for the remainder of the test!",
                           hostname, log_folder, mebibytes_used, limit_mebibytes_used, y_virtual_user_id);
        disk_space_warning_given = 1; // turn off further warnings.
        y_log_turn_off_permanently();
    }
}
示例#2
0
Action()
{
	char *results = NULL;
	int   rescnt  = 0;

	lr_save_string("199.35.107.2","DnsServer");	// Set DNS server IP Address
	lr_save_string("www.merc-int.com", "Hostname");	// Set hostname to resolve

	// Perform DNS Query
	results = (char *) ms_dns_query("DnsQuery",
			"URL=dns://{DnsServer}",
			"QueryHost={Hostname}",
		LAST);

	// List all the results... (if more than one)
	while (*results) {
		rescnt++;
		lr_log_message(
			lr_eval_string("(%d) IP address for {Hostname} is %s"),
			rescnt, 
			results);
		results = (char *) ms_dns_nextresult(results);
	}
	return 0;
}
示例#3
0
/*!
\brief Split a string into 2 parts using the search string. Save the right part into the result parameter.
\param [in] original_parameter The parameter to search.
\param [in] search The text preceding the text we're looking for.
\param [in] result_parameter The name of the parameter to store the result in.

\b Example:
\code
lr_save_string("AstrixObelixIdefix", "Test");
lr_message(lr_eval_string("Original: {Test}\n"));    // {Test}=AstrixObelixIdefix
y_right( "Test", "Obelix", "Test4" );
lr_message(lr_eval_string("New Param: {Test4}\n"));    //    {Test4}=Idefix
\endcode
\author Floris Kraak
*/
void y_right( const char *original_parameter, const char *search, const char *result_parameter)
{
    char* original = y_get_parameter_or_null(original_parameter);
    if( original == NULL )
    {
        lr_error_message("y_right(): Error: Parameter %s does not exist!", original_parameter);
        lr_abort();
    }
    else if( search == NULL || strlen(search) == 0 )
    {
        lr_save_string(original, result_parameter);
        lr_log_message("Warning: Empty search parameter passed to y_right()");
        return;
    }
    else
    {
        char* posPtr = (char *)strstr(original, search);
        //int pos = (int)(posPtr - original);
        //lr_log_message("y_right: original=%s, search=%s, resultParam=%s", original, search, result_parameter);
    
        if( posPtr == NULL )
        {
            lr_save_string(original, result_parameter);
            return;
        }
        //lr_log_message("pos = %d", pos);
        posPtr = posPtr + strlen(search);
        lr_save_string(posPtr, result_parameter);
    }
}
示例#4
0
/*!
\brief Split a string into 2 parts using the search string. Save the left part into the result parameter.
\param [in] original_parameter The parameter to search.
\param [in] search The text after the text we're looking for.
\param [in] result_parameter The name of the parameter to store the result in.

\b Example:
\code
lr_save_string("AstrixObelixIdefix", "Test");
lr_message(lr_eval_string("Original: {Test}\n"));    // {Test}=AstrixObelixIdefix
y_left( "Test", "Obelix", "Test2" );
lr_message(lr_eval_string("New Param: {Test2}\n"));    // {Test2}=Astrix
\endcode
\author Floris Kraak
*/
void y_left( const char *original_parameter, const char *search, const char *result_parameter )
{
    char *original = y_get_parameter_or_null(original_parameter);
    if( original == NULL )
    {
        lr_error_message("y_left(): Error: Parameter %s does not exist!", original_parameter);
        lr_abort();
    }
    else if( search == NULL || strlen(search) == 0 )
    {
        lr_save_string(original, result_parameter);
        lr_log_message("Warning: Empty search parameter passed to y_left()");
        return;
    }
    else
    {
        char *buffer;
        char *posPtr = (char *)strstr(original, search);
        int pos = (int)(posPtr - original);
        //lr_log_message("y_left: original=%s, search=%s, resultParam=%s", original, search, resultParam);

        if( posPtr == NULL )
        {
            lr_save_string(original, result_parameter);
            return;
        }
        //lr_log_message("pos = %d", pos);

        // Copy the original to a temporary buffer
        buffer = y_strdup(original);
        buffer[pos] = '\0'; // make the cut
        lr_save_string(buffer, result_parameter); // save the result
        free(buffer);
    }
}
示例#5
0
/*! \brief Fetch a specific item from a flow list, by name.
\param [in] flow_name The name of the flow to fetch.
\param [in] flow_list The flow list in question.
\param [in] flow_count The number of flows in the list.
\return A pointer to the requested flow.
\see y_flow_list.c, y_choose_flow(), y_exec_flow()
*/
y_flow* y_get_flow_by_name(char *flow_name, y_flow flow_list[], int flow_count)
{
    int i;
    lr_log_message("y_get_flow_by_name(%s)", flow_name);

    for(i=0; i < flow_count; i++)
    {
        y_flow *flow = &flow_list[i];

        //lr_log_message("Found name: %s", flow->name);
        if( strcmp(flow_name, flow->name) == 0 )
        {
            //lr_log_message("Match: %s", flow->name);
            return flow;
        }
    }
    lr_log_message("Name not found: %s", flow_name);
    return NULL;
}
示例#6
0
/*! \brief Calculate the total of the weights in a given flow list.

Given a flowlist of a specified length, calculate the total weight of all flows in a flow list.
This is used by other ylib functions. Calling it directly from a script should normally not be needed.

\see y_flow_list.c, y_choose_flow()
\param [in] flow_list An array of y_flow structs, each describing a specific choice in a clickpath.
\param [in] flow_count The number of flows in the list.
\author Floris Kraak
*/
int y_calc_flow_weight_total(y_flow flow_list[], int flow_count)
{
    int i, total = 0;
    for(i=0; i < flow_count; i++)
    {
        y_flow* flow = &flow_list[i];
        total += flow->weight;
    }
    lr_log_message("y_flow: Combined total of weights is: %d", total);
    return total;
}
示例#7
0
/*! \brief Execute a flow from a flow list.

Usually this is a flow as determined by y_choose_flow().
\see y_flow_list.c, y_choose_flow()
\param [in] chosen_flow The flow to execute.
\return the flow's function return value.
\author Floris Kraak
*/
int y_exec_flow(y_flow *chosen_flow)
{
    if(chosen_flow == NULL)
    {
        lr_log_message("Warning: Cannot execute NULL flow.");
    }
    else if(chosen_flow->name == NULL)
    {
        lr_log_message("Warning: Cannot execute a flow without a name!");
    }
    else if(chosen_flow->function == NULL)
    {
        lr_log_message("Warning: Cannot execute NULL flow function for flow %s", chosen_flow->name);
    }
    else
    {       
        y_flow_func *flow_function = chosen_flow->function;
        return flow_function(); // Run the flow.
    }
    return 0;
}
示例#8
0
/*! \brief Choose a flow from a list of flows. 
\param [in] flow_list An array of y_flow structs, each describing a specific choice in a clickpath.
\param [in] flow_count The number of flows in the list.
\return a pointer to a randomly chosen flow, or NULL if somehow the weights don't add up. (flow list corrupt, flow_count incorrect, etc.)

\see y_flow_list.c, y_exec_flow()
\note The flow_count argument should exactly match the number of flows in the array or the script might blow up with MEMORY_ACCESS_VIOLATION errors.
\author Floris Kraak
*/
y_flow* y_choose_flow(y_flow flow_list[], int flow_count)
{
    int i, lowerbound = 0;
    int cursor = 0;
    int roll = y_rand() % y_calc_flow_weight_total(flow_list, flow_count);

    lr_log_message("Roll: %d", roll);

    for(i=0; i < flow_count; i++)
    {
        y_flow *flow = &flow_list[i];
        int weight = flow->weight;
        cursor += weight;

        lr_log_message("weight cursor: %d", cursor);
        if(roll < cursor)
        {
            return flow;
        }
    }
    return NULL;
}
示例#9
0
/*!
\brief Split a string into 2 parts using the search string. Save the rightmost part into the result parameter.
This is almost the same as y_right(), but doesn't stop at the first match - instead, it uses the *last* match.
It's pretty much the difference between 'greedy' and 'not greedy' in a regular expression..

\param [in] original_parameter The parameter to search.
\param [in] search The text preceding the text we're looking for.
\param [in] result_parameter The name of the parameter to store the result in.

\b Example:
\code
lr_save_string("AstrixObelixIdefix", "Test");
lr_message(lr_eval_string("Original: {Test}\n"));    // {Test}=AstrixObelixIdefix
y_right( "Test", "Obelix", "Test4" );
lr_message(lr_eval_string("New Param: {Test4}\n"));    //    {Test4}=Idefix
\endcode
\author Floris Kraak
*/
void y_last_right( const char *original_parameter, const char *search, const char *result_parameter)
{
    char *result = y_get_parameter_or_null(original_parameter);
    if( result == NULL )
    {
        lr_error_message("y_last_right(): Error: Parameter %s does not exist!", original_parameter);
        lr_abort();
    }
    else if( search == NULL || strlen(search) == 0 )
    {
        lr_save_string(result, result_parameter);
        lr_log_message("Warning: Empty search parameter passed to y_last_right()");
        return;
    }
    else
    {
        char *posPtr;
        //lr_log_message("y_last_right: original=%s, search=%s, resultParam=%s", original, search, resultParameter);
        do 
        {
            posPtr = (char *)strstr(result, search);
            //pos = (int)(posPtr - result);
            //lr_log_message("pos = %d", pos);
    
            // not found, save what we have as the result.
            if( posPtr == NULL )
            {
                lr_save_string(result, result_parameter);
                return;
            }
            // found, update the result pointer and go find more..
            result = posPtr + strlen(search);
        } 
        while(1);
    }
}
示例#10
0
/*! \brief Log a message forcefully, bypassing the current log settings.

Typically used for generating datafiles within scripts with the loglevel set to OFF, or things of that sort.

\b Example:
\code
   lr_set_debug_message(LR_MSG_CLASS_DISABLE_LOG, LR_SWITCH_ON);
   lr_set_debug_message(LR_MSG_CLASS_AUTO_LOG, LR_SWITCH_OFF);
   lr_log_message("Before");              // Nothing gets logged here.
   y_log_force_message("Forced message"); // "Forced message" appears in the logs.
   lr_log_message("After");               // No output again.
\endcode
\author Floris Kraak
*/ 
void y_log_force_message(char *message)
{
    y_log_set_extended();
    lr_log_message( message );
    y_log_restore();
}
EmployerCreateAccount()
{
	int savedcount, duplicatecount;
	web_set_sockets_option("SSL_VERSION", "TLS1.1");
		
	web_reg_save_param("AUTH_TOKEN_1", "LB=<meta name=\"csrf-token\" content=\"", "RB=\" />", LAST); 
	
	lr_start_transaction("INTEG_EMPLYR_0002_Click_on_Create_Account");

	web_url("Create account", 
		"URL={HTTP}://{EnrollAppLandingPage}/users/sign_up", 
		"TargetFrame=", 
		"Resource=0", 
		"RecContentType=text/html", 
		"Referer={HTTP}://{EnrollAppLandingPage}/users/sign_in", 
		"Snapshot=t3.inf", 
		"Mode=HTML", 
		LAST);

	lr_end_transaction("INTEG_EMPLYR_0002_Click_on_Create_Account",LR_AUTO);
	
	lr_think_time(11);
	
	web_reg_save_param("AUTH_TOKEN_2", "LB=<meta name=\"csrf-token\" content=\"", "RB=\" />", LAST);
	web_reg_find("Text/IC=Your account has been created", "SaveCount=CreateAccountCount", LAST);

	lr_start_transaction("INTEG_EMPLYR_0003_Create_Account_Submit");
	
	web_submit_data("users", 
		"Action={HTTP}://{EnrollAppLandingPage}/users", 
		"Method=POST", 
		"TargetFrame=", 
		"RecContentType=text/html", 
		"Referer={HTTP}://{EnrollAppLandingPage}/users/sign_up", 
		"Snapshot=t4.inf", 
		"Mode=HTML", 
		"EncodeAtSign=YES", 
		ITEMDATA, 
		"Name=utf8", "Value=✓", ENDITEM, 
		"Name=authenticity_token", "Value={AUTH_TOKEN_1}", ENDITEM,  
		"Name=user[referer]", "Value={HTTP}://{EnrollAppLandingPage}/users/sign_in", ENDITEM, 
		"Name=user[email]", "Value={pEmpPrefix}{FEIN}@test.com", ENDITEM, 
		"Name=user[password]", "Value=Abcd!234", ENDITEM,
		"Name=user[password_confirmation]", "Value=Abcd!234", ENDITEM, 
		"Name=user[invitation_id]", "Value=", ENDITEM, 
		"Name=commit", "Value=Create account", ENDITEM, 	
		LAST);

	if (strcmp(lr_eval_string("{CreateAccountCount}"), "0") == 0)
	{
		lr_end_transaction("INTEG_EMPLYR_0003_Create_Account_Submit",LR_FAIL);
		lr_error_message("Failed to Create Account for::: %s%[email protected]", lr_eval_string("{pEmpPrefix}"), lr_eval_string("{FEIN}"));
		lr_exit(LR_EXIT_ITERATION_AND_CONTINUE, LR_AUTO);		
	}
	else
	{
		lr_log_message("Successfully created account for ::: %s%[email protected]", lr_eval_string("{pEmpPrefix}"), lr_eval_string("{FEIN}"));
		lr_end_transaction("INTEG_EMPLYR_0003_Create_Account_Submit",LR_PASS);
	}


	
	return 0;
}
示例#12
0
// --------------------------------------------------------------------------------------------------
// Search and replace.
// Find 'search' in 'parameter' and replace it with 'replace'.
// Replaces the originally passed-in parameter with the new one.
//
// Note: This one has a built-in search/y_replace limit when
// search > y_replace. It won't do it more than 'limit' times.
//
// @author Floris Kraak
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//        example usage:     
//             lr_save_string("test123", "par1");
//          y_replace("par1", "1", "ing1");        // {par1} now has the value testing123
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
y_replace( const char *parameter, const char *search, const char *replace)
{
   int slen, rlen, plen;      // lengte van search, replace, en basis string
   int i = 0;                 // aantal replacements
   int limit = 1000;          // replacement limiet als replace > search

   char *c;                   // punt waar change moet beginnen
   char *cend;                // einde van de change = c+slen
   char *last;                // de \0 slotbyte van input string
   char *buffer;              // buffer voor bewerkingen
   char *string;              // originele string waar we in zoeken

   if ((search == NULL)     || (strlen(search) <1)) 
       return;
   if (!search || !replace)      return;   // ongeldige search of_replace
   if (!strcmp(search, replace)) return;   // search == replace: geen wijziging

   slen = strlen (search);          // de lengte van search
   rlen = strlen (replace);         // de lengte van replace

   string = y_get_parameter(parameter); // <-- memory allocated by loadrunner, too small if replace > search
   plen = strlen(string);

   //lr_log_message("y_replace(%s, %s, %s) - slen %d, rlen %d, plen %d", parameter, search, replace, slen, rlen, plen);
    
   if ( rlen > slen)
   {
      // Reserve memory for -limit- replacements.
      size_t size = plen + ((rlen-slen) * limit);
      buffer = y_mem_alloc( size );
      snprintf( buffer, size, "%s", string );
   }
   else
   {
      // No need to reserve memory
      buffer = string;
   }

   last = buffer + strlen(buffer) +1;      // het einde van de string, de null byte
   c = buffer;                             // initialiseer c - buffer moet intact blijven

   while (c = (char*) strstr(c, search))   // doorzoek de search string vanaf waar je gebleven bent
   {
      //lr_output_message("c:%s", c);
 
      i++;
      if (slen != rlen)                    // zijn search en replace van verschillende lengte?
      {
         if( i >= limit )
         {
            lr_log_message("Unable to handle more than %d search-and-replaces, apologies for the inconvenience.", limit);
            break;
         }
         cend = c+slen;                        // cend is de plaats van waaraf de string moet opschuiven
         //lr_output_message("memmove(dest=%d, src=%d, size=%d)", (long)(c+rlen), (long)(cend), (long)(last-cend) );
         memmove (c+rlen , cend, last-cend);   // verplaats de rest van de string - als de geheugenberekening niet klopt gaat dit stuk!
         //lr_output_message("memmove completed, result = %s", c);
         last = last - slen + rlen;            // en bereken het nieuwe eindpunt
      }
      memmove(c, replace, rlen);  // execute the replacement
      c += rlen;                  // start the next search at the point where the replacement ended
   }
   lr_save_string(buffer, parameter);

   if( rlen > slen )
   {
      free(buffer);
   }
}
示例#13
0
/*!
This function uses a given set of characters to create words, separated by spaces.
The words are minimal \e minWordLength characters long, and maximum \e minWordLength characters.
The total length of the line is minimal \e minimumLength and maimum \e maximumLength long.

\b Example:
\code
// Generates a string of minimal 3 and max 20 characters, 
// with words of minimal 1 and maximal 3 charactes.
// Chooses only characters a, c, d or d.
y_random_string_buffer_core("uitvoer", 3,20, 1, 3, "abcd");

// Generates some sort of mock morse-code of exactly 30 characters.
// with words of minimal 1 and maximal 3 charactes.
// Chooses only characters a, c, d or d.
y_random_string_buffer_core("uitvoer", 3,20, 1, 3, "abcd"); // could result in "ccc db dac c"
\endcode

@param[out] parameter Name of the LR-parameter in which the result is stored
@param[in] minimumLength Minumum length of the string
@param[in] maximumLength Maximum length of the string
@param[in] minWordLength Minimum length of the words within the string
@param[in] maxWordLength Minimum length of the words within the string
@param[in] characterSet The string is build from this string of characters
\return void
\author Floris Kraak / Raymond de Jongh

\sa y_random_number_buffer
\sa y_random_string_buffer_curses
\sa y_random_string_buffer
\sa y_random_string_buffer_hex
*/
void y_random_string_buffer_core(const char *parameter, int minimumLength, int maximumLength, 
                                 int minWordLength, int maxWordLength, char *characterSet)
{
   char *buffer;
   int charSetSize; // length of the characterSet
   int length = 0;
   int max = -1;

   char randomNumber;
   int lettersInWord;

   charSetSize=strlen(characterSet);

   //lr_message("minimumLength %d -- maximumLength %d -- minWordLength %d -- maxWordLength %d", 
   //      minimumLength, maximumLength, minWordLength, maxWordLength);

   // error checks - lots of code that saves us headaches later
   if( minimumLength < 0 ) {
      lr_error_message( "minimumLength less than 0 (%d)", minimumLength );
   }
   else if( maximumLength < 1 ) {
      lr_error_message( "maximumLength less than 1 (%d)", maximumLength );
   }
   else if( maximumLength > (1024 * 1024) ) {
      lr_error_message( "maximumLength too big (%d)", maximumLength );
   }
   else if( maximumLength < minimumLength ) {
      lr_error_message( "minimumLength (%d) bigger than maximumLength (%d)", minimumLength, maximumLength );
   }
   else if(maximumLength > minimumLength) {
      // Not an error
      max = y_rand_between(minimumLength, maximumLength);
      lr_log_message("Max: %d", max);
   }
   else if(maximumLength == minimumLength) {
      // Not an error either
      max = maximumLength;
   }
   else {
      lr_error_message("This can never happen. If we reach this point it's a bug.");
   }

   // if we got an error
   if( max < 0 )
   {
      lr_set_transaction_status(LR_FAIL);
      lr_exit(LR_EXIT_ITERATION_AND_CONTINUE, LR_FAIL);
   }

   // get memory for the buffer
   buffer = (char *)y_mem_alloc( max +1 );
   // note: if this fails y_mem_alloc() aborts the script, so no error handling needed.

   while( length < max )
   {
//      lr_message("Length: %d   max: %d", length, max);
//      lettersInWord = ((y_rand() % 8) + 2);
      if( maxWordLength == 0 )
      {
         lettersInWord = maximumLength;
      }
      else
      {
         lettersInWord = y_rand_between(minWordLength, maxWordLength);
         if( lettersInWord < 0 )
         {
            lr_error_message( "y_rand_between() returned an errorcode (%d)", lettersInWord );
            lr_set_transaction_status(LR_FAIL);
            lr_exit(LR_EXIT_ITERATION_AND_CONTINUE, LR_FAIL);
         }
      }

      while( lettersInWord-- && (length < (max)) )
      {
         randomNumber = (char) (y_rand() % charSetSize);
         buffer[length++] = characterSet[randomNumber];
      }

      if( maxWordLength != 0 )
      {
         if( length < max -1 )
         {
            buffer[length++] = ' ';
         }
      }
   }
   buffer[max] = '\0';

   lr_save_string(buffer, parameter);
   free(buffer);
}