diff options
author | Benoit Foucher <benoit@zeroc.com> | 2016-12-15 16:09:25 +0100 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2016-12-15 16:09:25 +0100 |
commit | 49e1618006301fdbe090f11851557c386466028c (patch) | |
tree | a0d206bfb536995e959f6b4d2b2671e3e0b362e3 | |
parent | Fix (ICE-7111) - iceboxnet --version/-v (diff) | |
download | ice-49e1618006301fdbe090f11851557c386466028c.tar.bz2 ice-49e1618006301fdbe090f11851557c386466028c.tar.xz ice-49e1618006301fdbe090f11851557c386466028c.zip |
iOS C++ controller fixes
-rw-r--r-- | cpp/test/include/TestHelper.h | 1 | ||||
-rw-r--r-- | cpp/test/ios/controller/Bundle/ControllerI.mm | 116 | ||||
-rw-r--r-- | cpp/test/ios/controller/C++ Test Controller.xcodeproj/project.pbxproj | 31 | ||||
-rw-r--r-- | cpp/test/ios/controller/Classes/Base.lproj/Main.storyboard | 42 | ||||
-rw-r--r-- | cpp/test/ios/controller/Classes/ViewController.h | 7 | ||||
-rw-r--r-- | cpp/test/ios/controller/Classes/ViewController.m | 107 | ||||
-rw-r--r-- | scripts/Controller.ice | 4 | ||||
-rwxr-xr-x | scripts/Controller.py | 23 | ||||
-rw-r--r-- | scripts/LocalDriver.py | 10 | ||||
-rw-r--r-- | scripts/Util.py | 137 | ||||
-rw-r--r-- | scripts/tests/Ice/networkProxy.py | 4 |
11 files changed, 353 insertions, 129 deletions
diff --git a/cpp/test/include/TestHelper.h b/cpp/test/include/TestHelper.h index 6ea19e5b4cb..8c4d765d88c 100644 --- a/cpp/test/include/TestHelper.h +++ b/cpp/test/include/TestHelper.h @@ -18,6 +18,7 @@ namespace Test { + class MainHelper : public std::streambuf { public: diff --git a/cpp/test/ios/controller/Bundle/ControllerI.mm b/cpp/test/ios/controller/Bundle/ControllerI.mm index 406b33aa077..5f65e515712 100644 --- a/cpp/test/ios/controller/Bundle/ControllerI.mm +++ b/cpp/test/ios/controller/Bundle/ControllerI.mm @@ -13,6 +13,8 @@ #include <Controller.h> #include <TestHelper.h> +#include <dlfcn.h> + @protocol ViewController -(void) print:(NSString*)msg; -(void) println:(NSString*)msg; @@ -23,32 +25,32 @@ using namespace Test::Common; namespace { - + typedef int (*MAIN_ENTRY_POINT)(int argc, char** argv, Test::MainHelper* helper); typedef int (*SHUTDOWN_ENTRY_POINT)(); - + class MainHelperI : public Test::MainHelper, private IceUtil::Monitor<IceUtil::Mutex>, public IceUtil::Thread { public: - + MainHelperI(id<ViewController>, const string&, const StringSeq&); virtual ~MainHelperI(); - + virtual void serverReady(); virtual void shutdown(); virtual void waitForCompleted() {} virtual bool redirect(); virtual void print(const std::string&); - + virtual void run(); - + void completed(int); void waitReady(int) const; int waitSuccess(int) const; string getOutput() const; - + private: - + id<ViewController> _controller; std::string _dll; StringSeq _args; @@ -59,55 +61,57 @@ namespace int _status; std::ostringstream _out; }; - + class ProcessI : public Process { public: - + ProcessI(id<ViewController>, MainHelperI*); virtual ~ProcessI(); - + void waitReady(int, const Ice::Current&); int waitSuccess(int, const Ice::Current&); string terminate(const Ice::Current&); - + private: - + id<ViewController> _controller; IceUtil::Handle<MainHelperI> _helper; }; - + class ProcessControllerI : public ProcessController { public: - - ProcessControllerI(id<ViewController>); - + + ProcessControllerI(id<ViewController>, NSString*, NSString*); + #ifdef ICE_CPP11_MAPPING - virtual shared_ptr<ProcessPrx> - start(string, string, StringSeq, const Ice::Current&); + virtual shared_ptr<ProcessPrx> start(string, string, StringSeq, const Ice::Current&); + virtual string getHost(string, bool, const Ice::Current&); #else - virtual ProcessPrx - start(const string&, const string&, const StringSeq&, const Ice::Current&); + virtual ProcessPrx start(const string&, const string&, const StringSeq&, const Ice::Current&); + virtual string getHost(const string&, bool, const Ice::Current&); #endif - + private: - + id<ViewController> _controller; + string _ipv4; + string _ipv6; }; - + class ControllerHelper { public: - - ControllerHelper(id<ViewController>); + + ControllerHelper(id<ViewController>, NSString*, NSString*); virtual ~ControllerHelper(); - + private: - + Ice::CommunicatorPtr _communicator; }; - + } MainHelperI::MainHelperI(id<ViewController> controller, const string& dll, const StringSeq& args) : @@ -144,7 +148,7 @@ MainHelperI::shutdown() { return; } - + if(_dllTestShutdown) { _dllTestShutdown(); @@ -169,9 +173,9 @@ void MainHelperI::run() { NSString* bundlePath = [[NSBundle mainBundle] privateFrameworksPath]; - + bundlePath = [bundlePath stringByAppendingPathComponent:[NSString stringWithUTF8String:_dll.c_str()]]; - + NSURL* bundleURL = [NSURL fileURLWithPath:bundlePath]; _handle = CFBundleCreate(NULL, (CFURLRef)bundleURL); if(!_handle) @@ -180,7 +184,7 @@ MainHelperI::run() completed(EXIT_FAILURE); return; } - + CFErrorRef error = nil; Boolean loaded = CFBundleLoadExecutableAndReturnError(_handle, &error); if(error != nil || !loaded) @@ -189,7 +193,10 @@ MainHelperI::run() completed(EXIT_FAILURE); return; } - + + // The following call is necessary to prevent random failures from CFBundleGetFunctionPointerForName + dlsym(_handle, "dllTestShutdown"); + void* sym = CFBundleGetFunctionPointerForName(_handle, CFSTR("dllTestShutdown")); if(sym == 0) { @@ -200,7 +207,7 @@ MainHelperI::run() return; } _dllTestShutdown = (SHUTDOWN_ENTRY_POINT)sym; - + sym = CFBundleGetFunctionPointerForName(_handle, CFSTR("dllMain")); if(sym == 0) { @@ -210,7 +217,7 @@ MainHelperI::run() completed(EXIT_FAILURE); return; } - + MAIN_ENTRY_POINT dllMain = (MAIN_ENTRY_POINT)sym; char** argv = new char*[_args.size() + 1]; for(unsigned int i = 0; i < _args.size(); ++i) @@ -309,7 +316,8 @@ ProcessI::terminate(const Ice::Current& current) return _helper->getOutput(); } -ProcessControllerI::ProcessControllerI(id<ViewController> controller) : _controller(controller) +ProcessControllerI::ProcessControllerI(id<ViewController> controller, NSString* ipv4, NSString* ipv6) : + _controller(controller), _ipv4([ipv4 UTF8String]), _ipv6([ipv6 UTF8String]) { } @@ -329,23 +337,33 @@ ProcessControllerI::start(const string& testSuite, const string& exe, const Stri return ICE_UNCHECKED_CAST(ProcessPrx, c.adapter->addWithUUID(ICE_MAKE_SHARED(ProcessI, _controller, helper.get()))); } -ControllerHelper::ControllerHelper(id<ViewController> controller) +string +#ifdef ICE_CPP11_MAPPING +ProcessControllerI::getHost(string protocol, bool ipv6, const Ice::Current& c) +#else +ProcessControllerI::getHost(const string& protocol, bool ipv6, const Ice::Current& c) +#endif +{ + return ipv6 ? _ipv6 : _ipv4; +} + +ControllerHelper::ControllerHelper(id<ViewController> controller, NSString* ipv4, NSString* ipv6) { Ice::registerIceDiscovery(); - + Ice::InitializationData initData = Ice::InitializationData(); initData.properties = Ice::createProperties(); initData.properties->setProperty("Ice.ThreadPool.Server.SizeMax", "10"); initData.properties->setProperty("IceDiscovery.DomainId", "TestController"); - initData.properties->setProperty("IceDiscovery.Interface", "127.0.0.1"); - initData.properties->setProperty("Ice.Default.Host", "127.0.0.1"); + initData.properties->setProperty("IceDiscovery.Interface", [ipv4 UTF8String]); + initData.properties->setProperty("Ice.Default.Host", [ipv4 UTF8String]); initData.properties->setProperty("ControllerAdapter.Endpoints", "tcp"); //initData.properties->setProperty("Ice.Trace.Network", "2"); //initData.properties->setProperty("Ice.Trace.Protocol", "2"); initData.properties->setProperty("ControllerAdapter.AdapterId", Ice::generateUUID()); - + _communicator = Ice::initialize(initData); - + Ice::ObjectAdapterPtr adapter = _communicator->createObjectAdapter("ControllerAdapter"); Ice::Identity ident; #if TARGET_IPHONE_SIMULATOR != 0 @@ -354,7 +372,7 @@ ControllerHelper::ControllerHelper(id<ViewController> controller) ident.category = "iPhoneOS"; #endif ident.name = [[[NSBundle mainBundle] bundleIdentifier] UTF8String]; - adapter->add(ICE_MAKE_SHARED(ProcessControllerI, controller), ident); + adapter->add(ICE_MAKE_SHARED(ProcessControllerI, controller, ipv4, ipv6), ident); adapter->activate(); } @@ -370,15 +388,19 @@ extern "C" { void -startController(id<ViewController> controller) +startController(id<ViewController> controller, NSString* ipv4, NSString* ipv6) { - controllerHelper = new ControllerHelper(controller); + controllerHelper = new ControllerHelper(controller, ipv4, ipv6); } void stopController() { - delete controllerHelper; + if(controllerHelper) + { + delete controllerHelper; + controllerHelper = 0; + } } } diff --git a/cpp/test/ios/controller/C++ Test Controller.xcodeproj/project.pbxproj b/cpp/test/ios/controller/C++ Test Controller.xcodeproj/project.pbxproj index 6ec0a93ba1c..4903666f1fd 100644 --- a/cpp/test/ios/controller/C++ Test Controller.xcodeproj/project.pbxproj +++ b/cpp/test/ios/controller/C++ Test Controller.xcodeproj/project.pbxproj @@ -7,7 +7,9 @@ objects = { /* Begin PBXBuildFile section */ - 1440D8731E01877300CF7ED3 /* Controller.ice in Sources */ = {isa = PBXBuildFile; fileRef = 14905C6D1DF991F2002AE61B /* Controller.ice */; }; + 1419EB451E028A0700352FD7 /* Controller.ice in Resources */ = {isa = PBXBuildFile; fileRef = 1419EB441E028A0700352FD7 /* Controller.ice */; }; + 1419EB461E028A3300352FD7 /* Controller.ice in Sources */ = {isa = PBXBuildFile; fileRef = 1419EB441E028A0700352FD7 /* Controller.ice */; }; + 1419EB471E028A3A00352FD7 /* Controller.ice in Sources */ = {isa = PBXBuildFile; fileRef = 1419EB441E028A0700352FD7 /* Controller.ice */; }; 1440D8761E0187BA00CF7ED3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14B70D0F1E0160FD00118DE3 /* UIKit.framework */; }; 1440D8841E0188A600CF7ED3 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1440D8821E0188A600CF7ED3 /* Info.plist */; }; 1440D88A1E0189F300CF7ED3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1440D8891E0189F300CF7ED3 /* Foundation.framework */; }; @@ -34,7 +36,6 @@ 14905C611DF98FD8002AE61B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 14905C601DF98FD8002AE61B /* Assets.xcassets */; }; 14905C641DF98FD8002AE61B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 14905C621DF98FD8002AE61B /* LaunchScreen.storyboard */; }; 14E398261E01B14B00A89291 /* ControllerI.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1440D8811E0188A600CF7ED3 /* ControllerI.mm */; }; - 14E398271E01B14B00A89291 /* Controller.ice in Sources */ = {isa = PBXBuildFile; fileRef = 14905C6D1DF991F2002AE61B /* Controller.ice */; }; 14E398291E01B14B00A89291 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14B70D0F1E0160FD00118DE3 /* UIKit.framework */; }; 14E3982B1E01B14B00A89291 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1440D8891E0189F300CF7ED3 /* Foundation.framework */; }; 14E398361E01B18100A89291 /* Cpp98ControllerBundle.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 14E398311E01B14B00A89291 /* Cpp98ControllerBundle.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -110,6 +111,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 1419EB441E028A0700352FD7 /* Controller.ice */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Controller.ice; path = ../../../../../scripts/Controller.ice; sourceTree = "<group>"; }; 1440D86C1E0186FF00CF7ED3 /* Cpp11ControllerBundle.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Cpp11ControllerBundle.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 1440D8811E0188A600CF7ED3 /* ControllerI.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ControllerI.mm; path = Bundle/ControllerI.mm; sourceTree = SOURCE_ROOT; }; 1440D8821E0188A600CF7ED3 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Bundle/Info.plist; sourceTree = SOURCE_ROOT; }; @@ -130,7 +132,6 @@ 14905C601DF98FD8002AE61B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 14905C631DF98FD8002AE61B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 14905C651DF98FD8002AE61B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; - 14905C6D1DF991F2002AE61B /* Controller.ice */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Controller.ice; path = ../../../../../scripts/Controller.ice; sourceTree = "<group>"; }; 14B70D0F1E0160FD00118DE3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 14E398311E01B14B00A89291 /* Cpp98ControllerBundle.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Cpp98ControllerBundle.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 14E398371E01B30500A89291 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; @@ -216,8 +217,8 @@ 14905C5A1DF98FD8002AE61B /* ViewController.h */, 14905C5B1DF98FD8002AE61B /* ViewController.m */, 14905C5D1DF98FD8002AE61B /* Main.storyboard */, - 14905C601DF98FD8002AE61B /* Assets.xcassets */, 14905C621DF98FD8002AE61B /* LaunchScreen.storyboard */, + 14905C601DF98FD8002AE61B /* Assets.xcassets */, 14905C651DF98FD8002AE61B /* Info.plist */, 14905C541DF98FD8002AE61B /* Supporting Files */, ); @@ -235,12 +236,11 @@ 14B70CFA1E015C8B00118DE3 /* Bundle */ = { isa = PBXGroup; children = ( + 1419EB441E028A0700352FD7 /* Controller.ice */, 1440D8811E0188A600CF7ED3 /* ControllerI.mm */, 1440D8821E0188A600CF7ED3 /* Info.plist */, - 14905C6D1DF991F2002AE61B /* Controller.ice */, ); - name = Bundle; - path = "C++ Controller Framework"; + path = Bundle; sourceTree = "<group>"; }; 14B70D0C1E0160F700118DE3 /* Frameworks */ = { @@ -409,6 +409,7 @@ files = ( 148ABA1A1DFB12C800594F70 /* client.p12 in Resources */, 14905C641DF98FD8002AE61B /* LaunchScreen.storyboard in Resources */, + 1419EB451E028A0700352FD7 /* Controller.ice in Resources */, 148ABA1B1DFB12C800594F70 /* server.p12 in Resources */, 14905C611DF98FD8002AE61B /* Assets.xcassets in Resources */, 14905C5F1DF98FD8002AE61B /* Main.storyboard in Resources */, @@ -463,8 +464,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 1419EB471E028A3A00352FD7 /* Controller.ice in Sources */, 1440D88C1E018B0C00CF7ED3 /* ControllerI.mm in Sources */, - 1440D8731E01877300CF7ED3 /* Controller.ice in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -492,8 +493,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 1419EB461E028A3300352FD7 /* Controller.ice in Sources */, 14E398261E01B14B00A89291 /* ControllerI.mm in Sources */, - 14E398271E01B14B00A89291 /* Controller.ice in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -538,11 +539,14 @@ CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = U4TBVKNQ7F; + ENABLE_BITCODE = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", ICE_CPP11_MAPPING, "$(inherited)", ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; HEADER_SEARCH_PATHS = ../../include; INFOPLIST_FILE = Bundle/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; @@ -567,10 +571,13 @@ CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = U4TBVKNQ7F; + ENABLE_BITCODE = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_PREPROCESSOR_DEFINITIONS = ( ICE_CPP11_MAPPING, ICE_STATIC_LIBS, ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; HEADER_SEARCH_PATHS = ../../include; INFOPLIST_FILE = Bundle/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; @@ -769,10 +776,13 @@ CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = U4TBVKNQ7F; + ENABLE_BITCODE = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; HEADER_SEARCH_PATHS = ../../include; INFOPLIST_FILE = Bundle/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; @@ -797,7 +807,10 @@ CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = U4TBVKNQ7F; + ENABLE_BITCODE = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_PREPROCESSOR_DEFINITIONS = ICE_STATIC_LIBS; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; HEADER_SEARCH_PATHS = ../../include; INFOPLIST_FILE = Bundle/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; diff --git a/cpp/test/ios/controller/Classes/Base.lproj/Main.storyboard b/cpp/test/ios/controller/Classes/Base.lproj/Main.storyboard index 9550d1821c9..7bd9da90e09 100644 --- a/cpp/test/ios/controller/Classes/Base.lproj/Main.storyboard +++ b/cpp/test/ios/controller/Classes/Base.lproj/Main.storyboard @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11542" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r"> <device id="retina4_7" orientation="portrait"> <adaptation id="fullscreen"/> </device> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11524"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <scenes> @@ -21,23 +21,55 @@ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> + <pickerView contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xR3-DO-y6j" userLabel="InterfaceIPv6"> + <rect key="frame" x="40" y="49" width="296" height="75"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> + <connections> + <outlet property="dataSource" destination="BYZ-38-t0r" id="qqe-Ub-kJJ"/> + <outlet property="delegate" destination="BYZ-38-t0r" id="F6m-Y2-o1H"/> + </connections> + </pickerView> <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" editable="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="nZ9-dY-qBC" userLabel="Output"> - <rect key="frame" x="16" y="20" width="343" height="627"/> - <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <rect key="frame" x="40" y="258" width="296" height="389"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <fontDescription key="fontDescription" type="system" pointSize="14"/> <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/> </textView> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="IPv4" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="StB-MO-pSa" userLabel="LabelInterfaceIPv4"> + <rect key="frame" x="40" y="28" width="34" height="21"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + <pickerView contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="BKi-XY-5kF" userLabel="InterfaceIPv6"> + <rect key="frame" x="40" y="161" width="296" height="75"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> + <connections> + <outlet property="dataSource" destination="BYZ-38-t0r" id="Ksd-8b-gVb"/> + <outlet property="delegate" destination="BYZ-38-t0r" id="NT1-QV-RAh"/> + </connections> + </pickerView> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="IPv6" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PhT-kW-Fyr" userLabel="LabelInterfaceIPv6"> + <rect key="frame" x="40" y="140" width="34" height="21"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> </subviews> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> </view> <connections> + <outlet property="interfaceIPv4" destination="xR3-DO-y6j" id="UZt-T6-HRh"/> + <outlet property="interfaceIPv6" destination="BKi-XY-5kF" id="1bQ-Zn-Pd2"/> <outlet property="output" destination="nZ9-dY-qBC" id="drk-4a-vAK"/> </connections> </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="136.80000000000001" y="138.98050974512745"/> + <point key="canvasLocation" x="133.59999999999999" y="136.28185907046478"/> </scene> </scenes> </document> diff --git a/cpp/test/ios/controller/Classes/ViewController.h b/cpp/test/ios/controller/Classes/ViewController.h index 1ce9af06153..645dbbab57f 100644 --- a/cpp/test/ios/controller/Classes/ViewController.h +++ b/cpp/test/ios/controller/Classes/ViewController.h @@ -14,11 +14,16 @@ -(void) println:(NSString*)msg; @end -@interface ViewController : UIViewController<ViewController> +@interface ViewController : UIViewController<ViewController, UIPickerViewDataSource, UIPickerViewDelegate> { @private + IBOutlet UIPickerView* interfaceIPv4; + IBOutlet UIPickerView* interfaceIPv6; IBOutlet UITextView* output; + void (*startController)(id<ViewController>, NSString*, NSString*); void (*stopController)(id<ViewController>); + NSMutableArray* interfacesIPv4; + NSMutableArray* interfacesIPv6; } @end diff --git a/cpp/test/ios/controller/Classes/ViewController.m b/cpp/test/ios/controller/Classes/ViewController.m index 10f99f408c6..92c1dfca50e 100644 --- a/cpp/test/ios/controller/Classes/ViewController.m +++ b/cpp/test/ios/controller/Classes/ViewController.m @@ -9,12 +9,19 @@ #import "ViewController.h" +#include <ifaddrs.h> +#include <arpa/inet.h> +#include <net/if.h> + @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; - + + // + // Load the controller bundle. + // NSString* bundlePath = [[NSBundle mainBundle] privateFrameworksPath]; #ifdef ICE_CPP11_MAPPING const char* bundle = "Cpp11ControllerBundle.bundle"; @@ -39,7 +46,7 @@ return; } - void (*startController)(id<ViewController>) = CFBundleGetFunctionPointerForName(handle, CFSTR("startController")); + startController = CFBundleGetFunctionPointerForName(handle, CFSTR("startController")); if(startController == 0) { NSString* err = [NSString stringWithFormat:@"Could not get function pointer startController from bundle %@", @@ -47,7 +54,7 @@ [self println:err]; return; } - + stopController = CFBundleGetFunctionPointerForName(handle, CFSTR("stopController")); if(stopController == 0) { @@ -56,20 +63,68 @@ [self println:err]; return; } - - (*startController)(self); + // + // Search for local network interfaces + // + interfacesIPv4 = [NSMutableArray array]; + [interfacesIPv4 addObject:@"127.0.0.1"]; + interfacesIPv6 = [NSMutableArray array]; + [interfacesIPv6 addObject:@"::1"]; + struct ifaddrs* ifap; + if(getifaddrs(&ifap) == 0) + { + struct ifaddrs* curr = ifap; + while(curr != 0) + { + if(curr->ifa_addr && curr->ifa_flags & IFF_UP && !(curr->ifa_flags & IFF_LOOPBACK)) + { + if(curr->ifa_addr->sa_family == AF_INET) + { + char buf[INET_ADDRSTRLEN]; + const struct sockaddr_in *addr = (const struct sockaddr_in*)curr->ifa_addr; + if(inet_ntop(AF_INET, &addr->sin_addr, buf, INET_ADDRSTRLEN)) + { + [interfacesIPv4 addObject:[NSString stringWithUTF8String:buf]]; + } + } + else if(curr->ifa_addr->sa_family == AF_INET6) + { + char buf[INET6_ADDRSTRLEN]; + const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)curr->ifa_addr; + if(inet_ntop(AF_INET6, &addr6->sin6_addr, buf, INET6_ADDRSTRLEN)) + { + [interfacesIPv6 addObject:[NSString stringWithUTF8String:buf]]; + } + } + } + curr = curr->ifa_next; + } + freeifaddrs(ifap); + } + + // By default, use the loopback + [interfaceIPv4 selectRow:0 inComponent:0 animated:NO]; + [interfaceIPv6 selectRow:0 inComponent:0 animated:NO]; + (*startController)(self, + [interfacesIPv4 objectAtIndex:[interfaceIPv4 selectedRowInComponent:0]], + [interfacesIPv6 objectAtIndex:[interfaceIPv6 selectedRowInComponent:0]]); } + - (void) dealloc { (*stopController)(self); } + -(void) write:(NSString*)msg { [output insertText:msg]; [output layoutIfNeeded]; [output scrollRangeToVisible:NSMakeRange([output.text length] - 1, 1)]; } + +#pragma mark ViewController + -(void) print:(NSString*)msg { [self performSelectorOnMainThread:@selector(write:) withObject:msg waitUntilDone:NO]; @@ -78,4 +133,46 @@ { [self print:[msg stringByAppendingString:@"\n"]]; } + +#pragma mark UIPickerViewDelegate + +- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component +{ + if(pickerView == interfaceIPv4) + { + return [interfacesIPv4 objectAtIndex:row]; + } + else + { + return [interfacesIPv6 objectAtIndex:row]; + } +} + +- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component +{ + (*stopController)(self); + (*startController)(self, + [interfacesIPv4 objectAtIndex:[interfaceIPv4 selectedRowInComponent:0]], + [interfacesIPv6 objectAtIndex:[interfaceIPv6 selectedRowInComponent:0]]); +} + +#pragma mark UIPickerViewDataSource + +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView +{ + return 1; +} + +- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component +{ + if(pickerView == interfaceIPv4) + { + return interfacesIPv4.count; + } + else + { + return interfacesIPv6.count; + } +} + @end diff --git a/scripts/Controller.ice b/scripts/Controller.ice index 41c751d7880..7517b2ec457 100644 --- a/scripts/Controller.ice +++ b/scripts/Controller.ice @@ -77,6 +77,8 @@ interface ProcessController { Process* start(string testsuite, string exe, StringSeq args) throws ProcessFailedException; + + string getHost(string protocol, bool ipv6); }; interface Controller @@ -85,6 +87,8 @@ interface Controller throws TestCaseNotExistException; OptionOverrides getOptionOverrides(); + + StringSeq getTestSuites(string mapping); }; }; diff --git a/scripts/Controller.py b/scripts/Controller.py index a13f0c69dc4..806c00802eb 100755 --- a/scripts/Controller.py +++ b/scripts/Controller.py @@ -89,19 +89,6 @@ class ControllerDriver(Driver): def startServerSide(self, config, c): self.updateCurrent(config) - - # Depending on the configuration, either use an IPv4, IPv6 or BT address for Ice.Default.Host - if self.current.config.ipv6: - if not self.driver.hostIPv6: - raise Test.Common.TestCaseFailedException("no IPv6 address set with --host-ipv6") - self.current.host = self.driver.hostIPv6 - elif self.current.config.protocol == "bt": - if not self.driver.hostBT: - raise Test.Common.TestCaseFailedException("no Bluetooth address set with --host-bt") - self.current.host = self.driver.hostBT - else: - self.current.host = self.driver.host if self.driver.host else self.driver.interface - try: self.current.serverTestCase._startServerSide(self.current) self.serverSideRunning = True @@ -119,10 +106,8 @@ class ControllerDriver(Driver): def runClientSide(self, host, config, c): self.updateCurrent(config) - if host: - current.host = host try: - self.current.clientTestCase._runClientSide(self.current) + self.current.clientTestCase._runClientSide(self.current, host) return self.current.result.getOutput() except Exception as ex: raise Test.Common.TestCaseFailedException(self.current.result.getOutput() + "\n" + str(ex)) @@ -161,10 +146,14 @@ class ControllerDriver(Driver): self.testcase = Test.Common.TestCasePrx.uncheckedCast(c.adapter.addWithUUID(TestCaseI(self.driver, current))) return self.testcase + def getTestSuites(mapping, c): + mapping = Mapping.getByName(mapping) + config = self.driver.configs[mapping] + return [t for t in mapping.getTestSuites() if not mapping.filterTestSuite(t.getId(), config, [], [])] + def getOptionOverrides(self, c): return Test.Common.OptionOverrides(ipv6=([False] if not self.driver.hostIPv6 else [False, True])) - self.initCommunicator() self.communicator.getProperties().setProperty("ControllerAdapter.Endpoints", self.endpoints) self.communicator.getProperties().setProperty("ControllerAdapter.AdapterId", Ice.generateUUID()) diff --git a/scripts/LocalDriver.py b/scripts/LocalDriver.py index 5dd0aec5ac2..8f848ba9f4b 100644 --- a/scripts/LocalDriver.py +++ b/scripts/LocalDriver.py @@ -154,6 +154,9 @@ class Executor: # class TestCaseRunner: + def getTestSuites(self, mapping, testsuites): + return testsuites + def filterOptions(self, options): return options @@ -189,6 +192,13 @@ class RemoteTestCaseRunner(TestCaseRunner): self.serverController = None self.serverOptions = {} + def getTestSuites(self, mapping, testsuites): + if self.clientController: + testsuites = [t for t in self.clientController.getTestSuites(mapping) if t in testsuites] + if self.serverController: + testsuites = [t for t in self.serverController.getTestSuites(mapping) if t in testsuites] + return testsuites + def filterOptions(self, options): import Ice options = options.copy() diff --git a/scripts/Util.py b/scripts/Util.py index 40053cb82d8..13e11cd1e43 100644 --- a/scripts/Util.py +++ b/scripts/Util.py @@ -1297,6 +1297,8 @@ class TestCase(Runnable): def _startServerSide(self, current): current.push(self) + # Set the host to use for the server side + current.host = current.driver.getProcessController(current).getHost(current) self.setupServerSide(current) try: self.startServerSide(current) @@ -1334,8 +1336,10 @@ class TestCase(Runnable): finally: server.teardown(current, success) - def _runClientSide(self, current): + def _runClientSide(self, current, host=None): current.push(self) + if host: + current.host = host self.setupClientSide(current) success = False try: @@ -1607,6 +1611,17 @@ class LocalProcessController(ProcessController): self.expect("[^\n]+ ready\n", timeout = startTimeout) readyCount -= 1 + def getHost(self, current): + # Depending on the configuration, either use an IPv4, IPv6 or BT address for Ice.Default.Host + if current.config.ipv6: + return current.driver.hostIPv6 + elif current.config.protocol == "bt": + if not current.driver.hostBT: + raise Test.Common.TestCaseFailedException("no Bluetooth address set with --host-bt") + return current.driver.hostBT + else: + return current.driver.host if current.driver.host else current.driver.interface + def start(self, process, current, args, props, envs, watchDog): # @@ -1667,14 +1682,37 @@ class RemoteProcessController(ProcessController): print(self.output) def __init__(self): - pass + self.processControllerProxies = {} def __str__(self): return "remote controller" + def getHost(self, current): + return self.getController(current).getHost(current.config.protocol, current.config.ipv6) + def getController(self, current): - # To be overriden in specialization to initialize the process controller proxy - return None + proxy = self.getControllerProxy(current) + if proxy in self.processControllerProxies: + return self.processControllerProxies[proxy] + + comm = current.driver.getCommunicator() + import Test + self.processControllerProxies[proxy] = Test.Common.ProcessControllerPrx.uncheckedCast(comm.stringToProxy(proxy)) + + if current.driver.controllerApp: + self.startControllerApp(current, self.processControllerProxies[proxy]) + + try: + self.processControllerProxies[proxy].ice_ping() + except: + raise RuntimeError("couldn't reach the remote controller `{0}'".format(proxy)) + return self.processControllerProxies[proxy] + + def startControllerApp(self, current, proxy): + pass + + def stopControllerApp(self, proxy): + pass def start(self, process, current, args, props, envs, watchDog): # Get the process controller @@ -1688,6 +1726,12 @@ class RemoteProcessController(ProcessController): current.writeln("(executing `{0}/{1}' on `{2}' args = {3})".format(current.testsuite, exe, self, args)) return RemoteProcessController.Process(exe, processController.start(str(current.testsuite), exe, args)) + def destroy(self, driver): + if driver.controllerApp: + for p in self.processControllerProxies.values(): + self.stopControllerApp(p) + + class iOSSimulatorProcessController(RemoteProcessController): device = "iOSSimulatorProcessController" @@ -1698,34 +1742,29 @@ class iOSSimulatorProcessController(RemoteProcessController): def __init__(self): RemoteProcessController.__init__(self) self.simulatorID = None - self.processControllers = {} def __str__(self): return "iOS Simulator" - def getController(self, current): + def getControllerProxy(self, current): + if isinstance(current.testcase.getMapping(), ObjCMapping): + return "iPhoneSimulator/com.zeroc.ObjC-Test-Controller" + else: + assert(isinstance(current.testcase.getMapping(), CppMapping)) + if current.config.cpp11: + return "iPhoneSimulator/com.zeroc.Cpp11-Test-Controller" + else: + return "iPhoneSimulator/com.zeroc.Cpp98-Test-Controller" + + def startControllerApp(self, current, proxy): if isinstance(current.testcase.getMapping(), ObjCMapping): appName = "ObjC Test Controller.app" - appBundleID = "com.zeroc.ObjC-Test-Controller" else: assert(isinstance(current.testcase.getMapping(), CppMapping)) if current.config.cpp11: appName ="C++11 Test Controller.app" - appBundleID = "com.zeroc.Cpp11-Test-Controller" else: appName ="C++98 Test Controller.app" - appBundleID = "com.zeroc.Cpp98-Test-Controller" - - proxy = "iPhoneSimulator/{0}".format(appBundleID) - if proxy in self.processControllers: - return self.processControllers[proxy] - - comm = current.driver.getCommunicator() - import Test - self.processControllers[proxy] = Test.Common.ProcessControllerPrx.uncheckedCast(comm.stringToProxy(proxy)) - - if current.driver.noControllerApp: - return self.processControllers[proxy] sys.stdout.write("launching simulator... ") sys.stdout.flush() @@ -1750,19 +1789,14 @@ class iOSSimulatorProcessController(RemoteProcessController): if not os.path.exists(path): raise RuntimeError("couldn't find iOS simulator controller application, did you build it?") run("xcrun simctl install \"{0}\" \"{1}\"".format(self.device, path)) - run("xcrun simctl launch \"{0}\" {1}".format(self.device, appBundleID)) + run("xcrun simctl launch \"{0}\" {1}".format(self.device, proxy.ice_getIdentity().name)) print("ok") - return self.processControllers[proxy] + def stopControllerApp(self, proxy): + run("xcrun simctl uninstall \"{0}\" {1}".format(self.device, proxy.ice_getIdentity().name)) def destroy(self, driver): - if driver.noControllerApp: - return - - for p in self.processControllers.values(): - appBundleId = p.ice_getIdentity().name - run("xcrun simctl uninstall \"{0}\" {1}".format(self.device, appBundleId)) - + RemoteProcessController.destroy(self, driver) if self.simulatorID: sys.stdout.write("destroying simulator... ") sys.stdout.flush() @@ -1786,10 +1820,22 @@ class iOSDeviceProcessController(RemoteProcessController): def __str__(self): return "iOS Device" - def getController(self, current): - # TODO: launch the controller on a connected iOS device + def getControllerProxy(self, current): + if isinstance(current.testcase.getMapping(), ObjCMapping): + return "iPhoneOS/com.zeroc.ObjC-Test-Controller" + else: + assert(isinstance(current.testcase.getMapping(), CppMapping)) + if current.config.cpp11: + return "iPhoneOS/com.zeroc.Cpp11-Test-Controller" + else: + return "iPhoneOS/com.zeroc.Cpp98-Test-Controller" + + def startControllerApp(self, current, proxy): + # TODO: use ios-deploy to deploy and run the application on an attached device? pass + def stopControllerApp(self, proxy): + pass class Driver: @@ -1863,7 +1909,7 @@ class Driver: @classmethod def getOptions(self): return ("dlrR", ["debug", "driver=", "filter=", "rfilter=", "host=", "host-ipv6=", "host-bt=", "interface=", - "no-controller-app"]) + "controller-app"]) @classmethod def usage(self): @@ -1881,7 +1927,7 @@ class Driver: print("--host-ipv6=<addr> The IPv6 address to use for Ice.Default.Host.") print("--host-bt=<addr> The Bluetooth address to use for Ice.Default.Host.") print("--interface=<IP> The multicast interface to use to discover controllers.") - print("--no-controller-app Don't start the process controller application.") + print("--controller-app Start the process controller application.") def __init__(self, options): self.debug = False @@ -1890,7 +1936,7 @@ class Driver: self.host = "" self.hostIPv6 = "" self.hostBT = "" - self.noControllerApp = False + self.controllerApp = False self.failures = [] parseOptions(self, options, { "d": "debug", @@ -1900,7 +1946,7 @@ class Driver: "rfilter" : "rfilters", "host-ipv6" : "hostIPv6", "host-bt" : "hostBT", - "no-controller-app" : "noControllerApp" }) + "controller-app" : "controllerApp" }) self.filters = [re.compile(a) for a in self.filters] self.rfilters = [re.compile(a) for a in self.rfilters] @@ -1996,15 +2042,22 @@ class Driver: if current.config.buildPlatform in self.processControllers: return self.processControllers[current.config.buildPlatform] + processController = None if current.config.buildPlatform == "iphonesimulator": - self.processControllers[current.config.buildPlatform] = iOSSimulatorProcessController() - return self.processControllers[current.config.buildPlatform] + processController = iOSSimulatorProcessController() + elif current.config.buildPlatform == "iphoneos": + processController = iOSDeviceProcessController() - # - # Fallback on the local process controller if no specific - # controller is needed for the given current - # - return self.localProcessController + if processController: + self.processControllers[current.config.buildPlatform] = processController + else: + # + # Fallback on the local process controller if no specific + # controller is needed for the given current + # + processController = self.localProcessController + + return processController def getProcessProps(self, current, ready, readyCount): props = {} diff --git a/scripts/tests/Ice/networkProxy.py b/scripts/tests/Ice/networkProxy.py index 77a4efe65cb..038ddbeb4ff 100644 --- a/scripts/tests/Ice/networkProxy.py +++ b/scripts/tests/Ice/networkProxy.py @@ -26,9 +26,7 @@ class NetworkProxyTestCase(ClientServerTestCase): self.proxy = None def canRun(self, current): - if current.config.buildPlatform == "iphonesimulator": - return False - elif current.config.buildPlatform == "iphoneos" and self.getName() == "HTTP client/server": + if current.config.buildPlatform in ["iphonesimulator", "iphoneos"]: return False return True |