mirror of
https://github.com/Netflix/dial-reference.git
synced 2026-06-08 02:49:58 +00:00
228 lines
7.3 KiB
C++
228 lines
7.3 KiB
C++
/*
|
|
* Copyright (c) 2014 Netflix, Inc.
|
|
* 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.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY NETFLIX, INC. 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 NETFLIX 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.
|
|
*/
|
|
|
|
#ifndef DIALCONFORMANCE_H
|
|
#define DIALCONFORMANCE_H
|
|
|
|
#include <memory>
|
|
#include "DialServer.h"
|
|
#include "DialClientInput.h"
|
|
|
|
using namespace std;
|
|
|
|
class DialConformance
|
|
{
|
|
public:
|
|
/**
|
|
* Create a singleton
|
|
*/
|
|
static DialConformance* create();
|
|
|
|
/**
|
|
* Get a pointer to the singleton
|
|
*/
|
|
static DialConformance* instance(void);
|
|
|
|
~DialConformance();
|
|
|
|
/**
|
|
* Run the test
|
|
*
|
|
* @param[in] pServer DIAL server to test
|
|
* @param[in] appList List of applications from the command line
|
|
* @param[in] inputFile Input file used to drive tests
|
|
* @param[in] outputFile File for writing the report. Use an
|
|
* empty string to use the default (report.html).
|
|
*
|
|
* @return 0 if successful, !0 otherwise
|
|
*/
|
|
int run(
|
|
DialServer* pServer,
|
|
vector<string>& appList,
|
|
string &inputFile,
|
|
string &outputFile );
|
|
private:
|
|
DialConformance();
|
|
DialServer* _pServer;
|
|
static DialConformance* sConformance;
|
|
DialClientInput _input;
|
|
|
|
/**
|
|
* Class to manage state for each application supported by the DIAL
|
|
* server. The application list is managed by the input file.
|
|
*/
|
|
class Application{
|
|
public:
|
|
enum State
|
|
{
|
|
STOPPED,
|
|
LAUNCHING, // application has just been launched, state
|
|
// has not been confirmed
|
|
LAUNCHED,
|
|
STOPPING // application has been stopped, state has not
|
|
// been confirmed
|
|
};
|
|
|
|
Application( string& name, DialServer *pServer, bool isErrorApp ) :
|
|
_isErrorApp(isErrorApp),
|
|
_pServer(pServer),
|
|
_state(STOPPED),
|
|
_stopurl(""),
|
|
_name(name) {}
|
|
~Application(){}
|
|
|
|
/**
|
|
* State Getter/Setters
|
|
*/
|
|
string getName() { return _name; }
|
|
State getState() { return _state; }
|
|
|
|
/**
|
|
* Returns true if the application is not a valid application
|
|
*/
|
|
bool isErrorApp() { return _isErrorApp; }
|
|
|
|
/**
|
|
* Launch an this application using the server that was stored when
|
|
* the class was created.
|
|
*
|
|
* @param[in] payload Data that is put into the POST data.
|
|
* @param[out] responseHeaders HTML response headers
|
|
* @param[out] responseBody HTML response body
|
|
*/
|
|
void launch(
|
|
string& payload,
|
|
string& responseHeaders,
|
|
string& responseBody )
|
|
{
|
|
_pServer->launchApplication(
|
|
_name, payload, responseHeaders, responseBody );
|
|
// TODO: Set state
|
|
|
|
// find Location in the header, store the stop url
|
|
if( !responseHeaders.empty() )
|
|
{
|
|
size_t pos, tmp = responseHeaders.find("Location");
|
|
if( tmp != responseHeaders.npos )
|
|
{
|
|
pos = responseHeaders.find("http", tmp);
|
|
size_t posEnd = responseHeaders.find("\n", pos+1);
|
|
if( posEnd != responseHeaders.npos )
|
|
_stopurl = responseHeaders.substr( pos, posEnd );
|
|
|
|
// chomp off the \r\n chars
|
|
DialConformance::chomp( _stopurl );
|
|
ATRACE("StopURL = %s********\n", _stopurl.c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the status of this application
|
|
*
|
|
* @param[out] responseHeaders HTML response headers
|
|
* @param[out] responseBody HTML response body
|
|
*/
|
|
void status(
|
|
string& responseHeaders,
|
|
string& responseBody )
|
|
{ _pServer->getStatus( _name, responseHeaders, responseBody ); }
|
|
|
|
/**
|
|
* Stop the application
|
|
*
|
|
* @param[out] responseHeaders HTML response headers
|
|
*/
|
|
void stop(
|
|
string& responseHeaders )
|
|
{ stop(_stopurl, responseHeaders ); }
|
|
|
|
/**
|
|
* Stop the application using a custom stop URL.
|
|
*
|
|
* @param[out] responseHeaders HTML response headers
|
|
*/
|
|
void stop( string& stopurl, string& responseHeaders)
|
|
{
|
|
if( !stopurl.empty() )
|
|
{
|
|
_pServer->stopApplication( stopurl, responseHeaders );
|
|
}
|
|
#ifdef DEBUG
|
|
else ATRACE("%s: Not sending stop, stop URL is empty\n", __FUNCTION__);
|
|
#endif
|
|
}
|
|
|
|
private:
|
|
bool _isErrorApp;
|
|
DialServer* _pServer;
|
|
State _state;
|
|
string _stopurl;
|
|
string _name;
|
|
};
|
|
// list of applications
|
|
vector<Application*> _apps;
|
|
|
|
// Internal helpers
|
|
void run_internal( DialServer* pServer );
|
|
bool execute_command( string& command, vector<string>& params );
|
|
|
|
// Get the Application pointer from an application string
|
|
Application* getApplication( string& command );
|
|
|
|
// extract the payload from a list of parameters
|
|
void getPayload(vector<string>& params, string& payload );
|
|
|
|
// Command execution functions
|
|
bool execute_launch( Application* pApp, vector<string>& params );
|
|
bool execute_status( Application* pApp, vector<string>& params );
|
|
bool execute_stop( Application* pApp, vector<string>& params );
|
|
|
|
// Helper function to extract a parameter.
|
|
void extractParamValue( string& param, string& value );
|
|
|
|
// Validation functions
|
|
bool validateParams( vector<string>& params,
|
|
string& responseHeaders, string& responseBody );
|
|
bool validateHttpResponse( string& headers, string& params );
|
|
bool validateHttpHeaders( string& headers, string& params );
|
|
bool validateResponseBody( string& headers, string& params );
|
|
|
|
public:
|
|
// Helper function to chomp off the carriage return line feed.
|
|
static void chomp(string& str)
|
|
{
|
|
string crlf("\r\n");
|
|
size_t pos = str.find_last_not_of( crlf );
|
|
if( pos != str.npos )
|
|
{
|
|
ATRACE("CHOMP\n");
|
|
str.erase(pos+1);
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif // DIALCONFORMANCE_H
|