Fix $XAPP_DESCRIPTOR_PATH parser bug
[ric-plt/xapp-frame-cpp.git] / test / config_test.cpp
1 // vim: ts=4 sw=4 noet :
2 /*
3 ==================================================================================
4        Copyright (c) 2020 Nokia
5        Copyright (c) 2020 AT&T Intellectual Property.
6
7    Licensed under the Apache License, Version 2.0 (the "License");
8    you may not use this file except in compliance with the License.
9    You may obtain a copy of the License at
10
11        http://www.apache.org/licenses/LICENSE-2.0
12
13    Unless required by applicable law or agreed to in writing, software
14    distributed under the License is distributed on an "AS IS" BASIS,
15    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16    See the License for the specific language governing permissions and
17    limitations under the License.
18 ==================================================================================
19 */
20
21 /*
22         Mnemonic:       config_test.cpp
23         Abstract:       Unit test to drive the config functions.
24
25         Date:           28 July 2020
26         Author:         E. Scott Daniels
27 */
28
29 #include <errno.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <string.h>
35 #include <time.h>
36
37 #include <string>
38 #include <memory>
39
40 #include "../src/xapp/xapp.hpp"
41
42 //#include "../src/json/jhash.hpp"
43 //#include "../src/json/jhash.cpp"
44
45 #include "../src/config/config.hpp"             // include things directly under test
46 #include "../src/config/config_cb.hpp"
47 #include "../src/config/config.cpp"
48 #include "../src/config/config_cb.cpp"
49
50 #include "ut_support.cpp"
51
52 char* data = (char *) "some data to validate in callback";
53 bool    callback_driven = false;
54 int             cb_errors = 0;
55
56
57 /*
58         Notification callback to see that it is driven on change.
59 */
60 void ncb( xapp::Config& c, void* data ) {
61         cb_errors += fail_if( data == NULL, "callback function did not get a good pointer" );
62
63         auto v = c.Get_control_value( "measurement_interval" );
64         cb_errors += fail_if( v != 1000, "measurement value in new file wasn't different" );
65
66         callback_driven = true;
67 }
68
69 int main( int argc, char** argv ) {
70         int             errors = 0;
71
72         set_test_name( "config_test" );
73
74
75         auto x = new Xapp( (char*) "43086", false );
76         if(     fail_if( x == NULL, "could not allocate xapp" )  > 0 ) {
77                 announce_results( 1 );
78                 exit( 1 );
79         }
80
81         fprintf( stderr, "<INFO> sussing info from config1.json\n" );
82         auto c = new xapp::Config( "config1.json" );
83         errors += fail_if( c == NULL, "unable to allocate a config with alternate name" );
84
85         auto s = c->Get_control_str( "ves_collector_address" );
86         errors += fail_if( s.empty(), "expected collector address control string not found" );
87         fprintf( stderr, "<INFO> collector address string var: %s\n", s.c_str() );
88
89         s = c->Get_port( "rmr-data-out" );
90         errors += fail_if( s.empty(), "expected port string not found" );
91         fprintf( stderr, "<INFO> port string var: %s\n", s.c_str() );
92
93         s = c->Get_port( "no-interface" );
94         errors += fail_if( ! s.empty(), "did not return empty when get port given an invalid name" );
95
96         s = c->Get_control_str( "no-such-control" );
97         errors += fail_if( ! s.empty(), "expected empty string for missing control got a string" );
98         if( ! s.empty() ) {
99                 fprintf( stderr, "<INFO> unexpected string for no such control name:  %s\n", s.c_str() );
100         }
101
102         auto v = c->Get_control_value( "measurement_interval" );
103         errors += fail_if( v == 0.0, "epxected measurement interval control value not found" );
104
105         auto b = c->Get_control_bool( "debug_mode" );
106         errors += fail_if( b == false, "epxected debug mode control boolean not found or had wrong value" );
107
108         auto cs = c->Get_contents();
109         if( fail_if( cs.empty(), "get contents returned an empty string" ) == 0 ) {
110                 fprintf( stderr, "<INFO> contents from file: %s\n", cs.c_str() );
111                 fprintf( stderr, "<INFO> ---------------------\n" );
112         } else {
113                 errors++;
114         }
115
116
117         // ----- test sussing path and using default name ----------------------------------
118         fprintf( stderr, "<INFO> sussing info from default (no env XAPP_DESCRIPTOR_PATH)\n" );
119         unsetenv( "XAPP_DESCRIPTOR_PATH" );
120         c = new xapp::Config(  );       // no env XAPP_DESCRIPTOR_PATH; assume the config-file.json is in the same directory
121         errors += fail_if( c->Get_contents().empty(), "no env XAPP_DESCRIPTOR_PATH : expected default config-file.json not found" );
122
123         fprintf( stderr, "<INFO> sussing info using XAPP_DESCRIPTOR_PATH as a directory without trailing slash\n" );
124         setenv( (char *) "XAPP_DESCRIPTOR_PATH", ".", 1 );                                      // this env var is a directory path
125         c = new xapp::Config(  );
126         errors += fail_if( c->Get_contents().empty(), "env XAPP_DESCRIPTOR_PATH=. : expected default config-file.json not found" );
127
128         fprintf( stderr, "<INFO> sussing info using XAPP_DESCRIPTOR_PATH as a directory with trailing slash\n" );
129         setenv( (char *) "XAPP_DESCRIPTOR_PATH", "./", 1 );                                     // this env var is a directory path with trailing slash
130         c = new xapp::Config(  );
131         errors += fail_if( c->Get_contents().empty(), "env XAPP_DESCRIPTOR_PATH=./ : expected default config-file.json not found" );
132
133         fprintf( stderr, "<INFO> sussing info from XAPP_DESCRIPTOR_PATH as filename\n" );
134         setenv( (char *) "XAPP_DESCRIPTOR_PATH", "./config1.json", 1 );         // this var name is ok; it's an fname
135         c = new xapp::Config(  );
136         errors += fail_if( c->Get_contents().empty(), "XAPP_DESCRIPTOR_PATH as fname : expected config1.json not found" );
137
138
139         // -------------- force callback to drive and test ---------------------------------
140
141         fprintf( stderr, "<INFO> load config-file.json for listener coverage testing\n" );
142         c = new xapp::Config( "config-file.json" );                     // set filname with out leading path
143         c->Set_callback( ncb, data );                                           // for coverage in listener
144
145         fprintf( stderr, "<INFO> load ./config-file.json for callback testing\n" );
146         c = new xapp::Config( "./config-file.json" );
147         c->Set_callback( ncb, data );
148
149         fprintf( stderr, "<INFO> sleeping to give callback time to be initialsed\n" );
150         sleep( 4 );
151         if( rename( (char *) "./config-file.json", (char *) "./tmp-config.json" ) == 0 ) {              // rename (should not cause callback)
152                 fprintf( stderr, "<INFO> file moved; sleeping a bit\n" );
153                 sleep( 3 );
154                 errors += fail_if( callback_driven, "callback was driven when file was deleted/moved away" );
155
156                 if( rename( (char *) "./tmp-config.json", (char *) "./config-file.json" ) == 0 ) {              // put it back to drive callback
157                         fprintf( stderr, "<INFO> sleeping to give callback time to be driven\n" );
158                         sleep( 3 );
159
160                         errors += fail_if( ! callback_driven, "callback was never executed" );
161                 } else {
162                         fprintf( stderr, "<WARN> attempt to move config file back failed: %s\n", strerror( errno ) );
163                 }
164         } else {
165                 fprintf( stderr, "<WARN> attempt to move config file away failed: %s\n", strerror( errno ) );
166         }
167
168
169         // ----- force errors where we can -----------------------------------------
170         fprintf( stderr, "<INFO> json parse errors expected to be reported now\n" );
171         c = new xapp::Config( "not-there.json" );                                               // json parse will fail
172
173         v = c->Get_control_value( "measurement_interval", 999 );
174         errors += fail_if( v != 999.0, "value from non-existant file wasn't default" );
175
176         s = c->Get_control_str( "ves_collector_address", "no-value" );
177         errors += fail_if( s.compare( "no-value" ) != 0, "string from non-existant file wasn't default" );
178
179         b = c->Get_control_bool( "debug_mode", false );
180         errors += fail_if( b, "boolean from non-existant file wasn't default" );
181
182         s = c->Get_port( "rmr-data-out" );
183         errors += fail_if( !s.empty(), "get port from bad jsonfile returned value" );
184
185         // ---------------------------- end housekeeping ---------------------------
186         announce_results( cb_errors + errors );
187         return !!errors;
188 }