#include <sys/inotify.h>
#include <unistd.h>
#include <string.h>
+#include <sys/stat.h>
#include <iostream>
#include <sstream>
if( errno == EAGAIN ) {
continue;
} else {
- fprintf( stderr, "<XFCPP ### CRIT ### config listener read err: %s\n", strerror( errno ) );
+ fprintf( stderr, "<XFCPP> ### CRIT ### config listener read err: %s\n", strerror( errno ) );
return;
}
}
fname = ufname;
std::ifstream ifs( fname );
+ if( ! ifs.is_open() ) {
+ fprintf( stderr, "<XFCPP> ### WARN ### unable to open %s; %s\n", fname.c_str(), strerror( errno ) );
+ }
+
std::string st( (std::istreambuf_iterator<char>( ifs ) ), (std::istreambuf_iterator<char>() ) );
auto new_jh = std::shared_ptr<xapp::Jhash>( new xapp::Jhash( st.c_str() ) );
The actual meaning of the environment variable is confusing. The name is "path" which
should mean that this is the directory in which the config file lives, but the examples
- elsewhere suggest that this is a filename (either fully qualified or relative). For now
- we will assume that it's a file name, though we could add some intelligence to determine
- if it's a directory name or not if it comes to it.
+ elsewhere suggest that this is a filename (either fully qualified or relative). To prevent
+ errors, we use some intelligence to determine if it's a directory name or not if it comes to it.
*/
std::shared_ptr<xapp::Jhash> xapp::Config::jparse( ) {
const char* data;
+ std::string filename;
+ struct stat sb;
+
+ data = getenv( (const char *) "XAPP_DESCRIPTOR_PATH" );
+ if( data != NULL ) {
+ filename = data;
+ if( stat( data, &sb ) == 0 ) {
+ if( S_ISDIR( sb.st_mode ) ) {
+ filename.append( "/config-file.json" );
+ }
+ } else {
+ fprintf( stderr, "<XFCPP> ### ERR ### unable to stat env XAPP_DESCRIPTOR_PATH: %s\n", strerror( errno ) );
+ }
- if( (data = getenv( (const char *) "XAPP_DESCRIPTOR_PATH" )) == NULL ) {
- data = (const char *) "./config-file.json";
+ } else {
+ filename = "./config-file.json";
}
- return jparse( std::string( data ) );
+ return jparse( filename );
}
// --------------------- construction, destruction -------------------------------------------
errors += fail_if( c == NULL, "unable to allocate a config with alternate name" );
auto s = c->Get_control_str( "ves_collector_address" );
- errors += fail_if( s.empty(), "expected control string not found" );
+ errors += fail_if( s.empty(), "expected collector address control string not found" );
fprintf( stderr, "<INFO> collector address string var: %s\n", s.c_str() );
s = c->Get_port( "rmr-data-out" );
auto b = c->Get_control_bool( "debug_mode" );
errors += fail_if( b == false, "epxected debug mode control boolean not found or had wrong value" );
-
- // ----- test sussing path and using default name ----------------------------------
- fprintf( stderr, "<INFO> sussing info from default (no name)\n" );
- c = new xapp::Config( ); // drive for coverage
-
- fprintf( stderr, "<INFO> sussing info from default (env var == ./config1.json)\n" );
- setenv( (char *) "XAPP_DESCRIPTOR_PATH", "./config1.json", 1 ); // this var name is bad; it's not a path, but fname
- c = new xapp::Config( );
-
- s = c->Get_control_str( "ves_collector_address" );
- errors += fail_if( s.empty(), "expected collector address control string not found" );
- fprintf( stderr, "<INFO> string var: %s\n", s.c_str() );
-
- v = c->Get_control_value( "measurement_interval" );
- errors += fail_if( v == 0.0, "expected measurement interval control value not found" );
-
- b = c->Get_control_bool( "debug_mode" );
- errors += fail_if( b == false, "expected debug mode control boolean not found" );
-
-
auto cs = c->Get_contents();
if( fail_if( cs.empty(), "get contents returned an empty string" ) == 0 ) {
fprintf( stderr, "<INFO> contents from file: %s\n", cs.c_str() );
}
+ // ----- test sussing path and using default name ----------------------------------
+ fprintf( stderr, "<INFO> sussing info from default (no env XAPP_DESCRIPTOR_PATH)\n" );
+ unsetenv( "XAPP_DESCRIPTOR_PATH" );
+ c = new xapp::Config( ); // no env XAPP_DESCRIPTOR_PATH; assume the config-file.json is in the same directory
+ errors += fail_if( c->Get_contents().empty(), "no env XAPP_DESCRIPTOR_PATH : expected default config-file.json not found" );
+
+ fprintf( stderr, "<INFO> sussing info using XAPP_DESCRIPTOR_PATH as a directory without trailing slash\n" );
+ setenv( (char *) "XAPP_DESCRIPTOR_PATH", ".", 1 ); // this env var is a directory path
+ c = new xapp::Config( );
+ errors += fail_if( c->Get_contents().empty(), "env XAPP_DESCRIPTOR_PATH=. : expected default config-file.json not found" );
+
+ fprintf( stderr, "<INFO> sussing info using XAPP_DESCRIPTOR_PATH as a directory with trailing slash\n" );
+ setenv( (char *) "XAPP_DESCRIPTOR_PATH", "./", 1 ); // this env var is a directory path with trailing slash
+ c = new xapp::Config( );
+ errors += fail_if( c->Get_contents().empty(), "env XAPP_DESCRIPTOR_PATH=./ : expected default config-file.json not found" );
+
+ fprintf( stderr, "<INFO> sussing info from XAPP_DESCRIPTOR_PATH as filename\n" );
+ setenv( (char *) "XAPP_DESCRIPTOR_PATH", "./config1.json", 1 ); // this var name is ok; it's an fname
+ c = new xapp::Config( );
+ errors += fail_if( c->Get_contents().empty(), "XAPP_DESCRIPTOR_PATH as fname : expected config1.json not found" );
+
+
// -------------- force callback to drive and test ---------------------------------
fprintf( stderr, "<INFO> load config-file.json for listener coverage testing\n" );