#!/usr/bin/env ruby # -------------------------------------------------------------------------- # # Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) # # # # Licensed under the Apache License, Version 2.0 (the "License"); you may # # not use this file except in compliance with the License. You may obtain # # a copy of the License at # # # # http://www.apache.org/licenses/LICENSE-2.0 # # # # Unless required by applicable law or agreed to in writing, software # # distributed under the License is distributed on an "AS IS" BASIS, # # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # # See the License for the specific language governing permissions and # # limitations under the License. # #--------------------------------------------------------------------------- # require 'pp' require 'digest/md5' require 'fileutils' ########################################### # Code to test compilation/linkning flags # ########################################### TestCodeServer=""" #include #include int main(int argc, char *argv[]) { xmlrpc_c::registry RequestManagerRegistry; return 0; }""" TestCodeClient=<<-EOT #include #include #include #include #include #include #include using namespace std; int main(int argc, char **) { if (argc-1 > 0) { cerr << "This program has no arguments" << endl; exit(1); } try { xmlrpc_env env; string const serverUrl("http://localhost:8080/RPC2"); string const methodAllocate("one.vmallocate"); xmlrpc_c::clientSimple myClient; xmlrpc_c::value resultSUBMIT; xmlrpc_env_init(&env); myClient.call(serverUrl, methodAllocate, "ss", &resultSUBMIT,"SESSION-GOLA&4H9109KVFSG", "MEMORY=345 CPU=4 DISK=[FILE=\\"img\\",TYPE=cd]" "DISK=[FILE=\\"../f\\"]"); xmlrpc_c::value_array resultArray = xmlrpc_c::value_array(resultSUBMIT); vector const paramArrayValue(resultArray.vectorValueValue()); //check posible Errors: xmlrpc_c::value * firstvalue; firstvalue = &(static_cast(paramArrayValue[0])); xmlrpc_c::value_boolean * status = &(static_cast(*firstvalue)); xmlrpc_c::value * secondvalue; secondvalue = &(static_cast(paramArrayValue[1])); xmlrpc_c::value_string * valueS = &(static_cast(*secondvalue)); if(static_cast(*status)) { //Success, returns the id assigned to the VM: cout << "vmid returned: " << static_cast(*valueS) << endl; return 0; } else{ //Failure: string error_value=static_cast(*valueS); if (error_value.find("Error inserting",0)!=string::npos ) cout << "Error inserting VM in the database" << endl; else if (error_value.find("Error parsing",0)!=string::npos ) cout << "Error parsing VM template" << endl; else cout << "Unknown error " << static_cast(*valueS) << endl; }; } catch (girerr::error const error) { cerr << "Client threw error: " << error.what() << endl; //"Client threw error:" return 20; } catch (std::exception const e) { cerr << "Client threw unexpected error." << endl; //Unexpected error: return 999; } return 0; } EOT TestCode={ :client => TestCodeClient, :server => TestCodeServer } # Executes a command and discards stderr def exec_command(command) lambda { #STDERR.puts text text=`#{command} 2>/dev/null` text.gsub!("\n", " ") if $?!=0 STDERR.puts " Error calling #{command}" nil else text end } end # Adds fixed flags and libraries def flags_and_libs_array(flags, libs) lambda { libs_text=libs.collect {|lib| "-l"+lib }.join(' ') text=flags+" "+libs_text #STDERR.puts text text } end # Array with flags/libs to test Configs=[ # Configuration for fedora { :description => "pkg-config", :client => exec_command("pkg-config xmlrpc_client++ xmlrpc++ --libs"), :server => exec_command("pkg-config xmlrpc_server_abyss++ --static --libs") }, # Configuration using xmlrpc-c-config { :description => "xmlrpc-c-config", :client => exec_command("xmlrpc-c-config c++2 client --libs --cflags"), :server => exec_command("xmlrpc-c-config c++2 abyss-server --libs --cflags") }, # Debian lenny { :description => "mixed hardcoded libraries and xmlrpc-c-config (debian lenny)", :client => flags_and_libs_array("-I/usr/include -L/usr/lib", [ 'xmlrpc_client', 'xmlrpc_client', 'xmlrpc', 'xmlrpc_util', 'xmlrpc_xmlparse', 'xmlrpc_xmltok', 'xmlrpc_client++', 'xmlrpc++' ]), :server => exec_command("xmlrpc-c-config c++2 abyss-server --libs --cflags"), }, # Configuration for Mac OS X and Debian { :description => "hardcoded libraries for Mac OS X (installed using port)", :server => flags_and_libs_array("-I/opt/local/include -L/opt/local/lib", [ 'wwwxml', 'xmltok', 'xmlparse', 'wwwzip', 'wwwinit', 'wwwapp', 'wwwtelnet', 'wwwhtml', 'wwwnews', 'wwwhttp', 'wwwmime', 'wwwgopher', 'wwwftp', 'wwwfile', 'wwwdir', 'wwwcache', 'wwwstream', 'wwwmux', 'wwwtrans', 'wwwcore', 'wwwutils', 'md5', 'dl', 'z', 'pthread', 'xmlrpc_client++', 'xmlrpc_client', 'xmlrpc++', 'xmlrpc', 'xmlrpc_util', 'xmlrpc_xmlparse', 'xmlrpc_xmltok', 'xmlrpc_server_abyss++', 'xmlrpc_server++', 'xmlrpc_server_abyss', 'xmlrpc_server', 'xmlrpc_abyss', ]), :client => flags_and_libs_array("-I/opt/local/include -L/opt/local/lib", [ 'curl', 'xmlrpc_client++', 'xmlrpc_client', 'xmlrpc++', 'xmlrpc', 'xmlrpc_util', 'xmlrpc_xmlparse', 'xmlrpc_xmltok', 'wwwxml', 'xmltok', 'xmlparse', 'wwwzip', 'wwwinit', 'wwwapp', 'wwwtelnet', 'wwwhtml', 'wwwnews', 'wwwhttp', 'wwwmime', 'wwwgopher', 'wwwftp', 'wwwfile', 'wwwdir', 'wwwcache', 'wwwstream', 'wwwmux', 'wwwtrans', 'wwwcore', 'wwwutils', 'm', 'md5' ]) }, # Example adding more custom libraries # { # :client => exec_command("xmlrpc-c-config client c++ --cflags --libs"), # :server => exec_command("xmlrpc-c-config abyss-server c++ --cflags --libs | tr '\\n' ' ' ; echo -lxmlrpc_server++") # }, ] # Compiles test code with given arguments def compile(file, args) logfile="#{file}.log" command="g++ #{file} -o #{file}.out #{ENV['LDFLAGS']} #{args} 1>>#{logfile} 2>&1" open(logfile, "a") {|f| f.write(command+"\n") } STDERR.puts command STDERR.puts "" out=system(command) end def gen_test_file(kind) dir='.xmlrpc_test' hash=Digest::MD5.hexdigest(Time.now.to_s+kind.to_s)[0..5] fname="xmlrpc_test."+hash+".cc" #fname="xmlrpc_test.cc" full_path=dir+"/"+fname FileUtils::mkdir_p(dir) f=open(full_path, "w") f.write(TestCode[kind]) f.close full_path end # Tests a configuration and writes build parameters if it is successful def test_config(kind, config) STDERR.puts "Testing recipe: "+config[:description].to_s args=config[kind.to_sym].call return nil if !args args.strip! name=gen_test_file(kind) exit_code=compile(name, args) #File.delete(name) File.delete(name+".out") if File.exists?(name+".out") return nil if !exit_code puts args true end # Test each of possible configurations and exits when it finds one working def search_config(kind) Configs.each {|config| found=test_config(kind,config) exit(0) if found } exit(1) end if !%w{client server}.include?ARGV[0] puts "You need to specify client or server" exit -1 end search_config(ARGV[0].to_sym)