diff --git a/Jenkinsfiles/mac b/Jenkinsfiles/mac index 98e6a4e..fcf2670 100644 --- a/Jenkinsfiles/mac +++ b/Jenkinsfiles/mac @@ -19,7 +19,7 @@ pipeline { cd osxscraper xcodebuild -list -project OSXScraper.xcodeproj xcodebuild -scheme OSXScraper build - + echo "Build OSXProxy..." cd ../osxproxy xcodebuild -list -project OSXProxy.xcodeproj @@ -33,7 +33,45 @@ pipeline { steps { timeout(time: 1, unit: 'HOURS'){ sh ''' - echo "Test(s) go here" + echo "[OSXScraper] Start testing" + mkdir -p testoutput + cd osxscraper + /Applications/Calculator.app/Contents/MacOS/Calculator & + + echo "[OSXScraper] build-for-testing" + xcodebuild build-for-testing -project OSXScraper.xcodeproj -scheme OSXScraper + + echo "clean the TCC.db" + sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" 'select * from access' + sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" "SELECT name FROM PRAGMA_TABLE_INFO('access')" + sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" "delete from access where client='edu.unc.OSXScraper' and service='kTCCServiceAccessibility'" + sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" 'select * from access' + + echo "[OSXScraper] test-without-building, run 1 case to enable Accessibility access magically" + xcodebuild test-without-building -project OSXScraper.xcodeproj -scheme OSXScraper -only-testing:OSXScraperTests/OSXScrapperTests/test001_LS_Self + + echo "enable the allow access in TCC.db" + sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" 'select * from access' + sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" "SELECT name FROM PRAGMA_TABLE_INFO('access')" + sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" 'UPDATE access SET allowed = "1";' + sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" 'select * from access' + + echo "[OSXScraper] test-without-building, run the testcases" + xcodebuild test-without-building -project OSXScraper.xcodeproj -scheme OSXScraper + cd - + ls -lht testoutput/ + echo "[OSXScraper] Testing Done" + + echo "[OSXProxy] Start testing" + cd osxproxy + + echo "[OSXProxy] build-for-testing" + xcodebuild build-for-testing -project OSXProxy.xcodeproj -scheme OSXProxy + + echo "[OSXProxy] test-without-building, run the testcases" + xcodebuild test-without-building -project OSXProxy.xcodeproj -scheme OSXProxy -skip-testing:OSXProxyUITests + + echo "[OSXProxy] Testing Done" ''' } } diff --git a/common/AppleConnection/AppleConnection/ClientHandler.m b/common/AppleConnection/AppleConnection/ClientHandler.m index aa000a8..5ebced7 100644 --- a/common/AppleConnection/AppleConnection/ClientHandler.m +++ b/common/AppleConnection/AppleConnection/ClientHandler.m @@ -86,6 +86,13 @@ - (id) init { - (void) initForClientSocket { _isServerSocket = NO; + if ( [[NSProcessInfo processInfo] environment][@"isUITest"] ) + { + isConnected = true; + [[NSNotificationCenter defaultCenter] postNotificationName:@"connectedInd" object:self]; + return; + } + CFReadStreamRef readStream; CFWriteStreamRef writeStream; CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)ipAddress, _port, &readStream, &writeStream); @@ -174,6 +181,30 @@ - (id) initForServerSocketWithtInputStream:(NSInputStream *) inStream outputStre - (void) sendMessage: (NSString *) message { static NSData *last_data; + if ( [[NSProcessInfo processInfo] environment][@"isUITest"] ) + { + return; + } + +#ifdef DEBUG + NSDictionary * instanceSetting = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"plist"]]; + NSString * logfolder = [instanceSetting objectForKey:@"xml_logfolder"]; + NSString * filename = nil; + if ((logfolder != Nil ) && ([logfolder length] != 0)) { + if (_isServerSocket == YES) { + filename = [NSString stringWithFormat:@"%@/scraper_%@.xml", logfolder, [NSDate date]]; + } + else { + filename = [NSString stringWithFormat:@"%@/proxy_%@.xml", logfolder, [NSDate date]]; + } + NSError * error = NULL; + if([message writeToFile:filename atomically:NO encoding:NSUTF8StringEncoding error:&error]) + { + NSLog( @"xml saving to %@", filename); + } + } +#endif + NSData *data = [[NSData alloc] initWithData:[message dataUsingEncoding:NSUTF8StringEncoding]]; if ([last_data isEqualToData:data]) { NSLog(@"Same data being sent repeatedly.Skipping send...\n"); diff --git a/osxproxy/OSXProxy.xcodeproj/project.pbxproj b/osxproxy/OSXProxy.xcodeproj/project.pbxproj index 0f96f07..6adb51d 100644 --- a/osxproxy/OSXProxy.xcodeproj/project.pbxproj +++ b/osxproxy/OSXProxy.xcodeproj/project.pbxproj @@ -7,8 +7,14 @@ objects = { /* Begin PBXBuildFile section */ + 0841824D240706DF00371637 /* OSXProxyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0841824C240706DF00371637 /* OSXProxyTests.m */; }; 08791EBA22331D0C009EB201 /* Params.m in Sources */ = {isa = PBXBuildFile; fileRef = 08791EB822331D0B009EB201 /* Params.m */; }; 08866A4B223981B3006F3473 /* XMLTags.m in Sources */ = {isa = PBXBuildFile; fileRef = 08866A49223981B3006F3473 /* XMLTags.m */; }; + 088E62A92448E3D2007C4AE5 /* OSXProxyUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 088E62A82448E3D2007C4AE5 /* OSXProxyUITests.m */; }; + 0894254424637F0E0065C587 /* test001_ServiceCode2_empty.xml in Resources */ = {isa = PBXBuildFile; fileRef = 0894254124637F0E0065C587 /* test001_ServiceCode2_empty.xml */; }; + 0894254524637F0E0065C587 /* test002_testServiceCode2.xml in Resources */ = {isa = PBXBuildFile; fileRef = 0894254224637F0E0065C587 /* test002_testServiceCode2.xml */; }; + 0894254624637F0E0065C587 /* test003_ServiceCode4.xml in Resources */ = {isa = PBXBuildFile; fileRef = 0894254324637F0E0065C587 /* test003_ServiceCode4.xml */; }; + 08942547246463AA0065C587 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C93FD3A198ADBD700227E47 /* Cocoa.framework */; }; 0DB105901DBC2E18004289E7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DB1058E1DBC2E18004289E7 /* AppDelegate.m */; }; 0DB105921DBC2E30004289E7 /* Settings.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0DB105911DBC2E30004289E7 /* Settings.plist */; }; 0DB105941DBC2FB4004289E7 /* RemoteExplorerWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0DB105931DBC2FB4004289E7 /* RemoteExplorerWindowController.xib */; }; @@ -57,11 +63,37 @@ 9C93FD3B198ADBD700227E47 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C93FD3A198ADBD700227E47 /* Cocoa.framework */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 0841824F240706DF00371637 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9C93FD2F198ADBD700227E47 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9C93FD36198ADBD700227E47; + remoteInfo = OSXProxy; + }; + 088E619F2448BE01007C4AE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9C93FD2F198ADBD700227E47 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9C93FD36198ADBD700227E47; + remoteInfo = OSXProxy; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ + 0841824A240706DF00371637 /* OSXProxyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OSXProxyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 0841824C240706DF00371637 /* OSXProxyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OSXProxyTests.m; sourceTree = ""; }; + 0841824E240706DF00371637 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 08791EB822331D0B009EB201 /* Params.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Params.m; path = ../common/AppleXMLSerializer/AppleXMLSerializer/src/Models/Params.m; sourceTree = ""; }; 08791EB922331D0B009EB201 /* Params.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Params.h; path = ../common/AppleXMLSerializer/AppleXMLSerializer/src/Models/Params.h; sourceTree = ""; }; 08866A49223981B3006F3473 /* XMLTags.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XMLTags.m; path = ../common/AppleXMLSerializer/AppleXMLSerializer/src/GDataXML/XMLTags.m; sourceTree = ""; }; 08866A4A223981B3006F3473 /* XMLTags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMLTags.h; path = ../common/AppleXMLSerializer/AppleXMLSerializer/src/GDataXML/XMLTags.h; sourceTree = ""; }; + 088E619A2448BE01007C4AE5 /* OSXProxyUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OSXProxyUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 088E619E2448BE01007C4AE5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 088E62A82448E3D2007C4AE5 /* OSXProxyUITests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSXProxyUITests.m; sourceTree = ""; }; + 0894254124637F0E0065C587 /* test001_ServiceCode2_empty.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = test001_ServiceCode2_empty.xml; sourceTree = ""; }; + 0894254224637F0E0065C587 /* test002_testServiceCode2.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = test002_testServiceCode2.xml; sourceTree = ""; }; + 0894254324637F0E0065C587 /* test003_ServiceCode4.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = test003_ServiceCode4.xml; sourceTree = ""; }; 0DB1058E1DBC2E18004289E7 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = OSXProxy/AppDelegate.m; sourceTree = ""; }; 0DB1058F1DBC2E18004289E7 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = OSXProxy/AppDelegate.h; sourceTree = ""; }; 0DB105911DBC2E30004289E7 /* Settings.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Settings.plist; path = OSXProxy/Settings.plist; sourceTree = ""; }; @@ -148,10 +180,25 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 08418247240706DF00371637 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 088E61972448BE01007C4AE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 9C93FD34198ADBD700227E47 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 08942547246463AA0065C587 /* Cocoa.framework in Frameworks */, 9C93FD3B198ADBD700227E47 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -159,6 +206,27 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 0841824B240706DF00371637 /* OSXProxyTests */ = { + isa = PBXGroup; + children = ( + 0841824C240706DF00371637 /* OSXProxyTests.m */, + 0894254124637F0E0065C587 /* test001_ServiceCode2_empty.xml */, + 0894254224637F0E0065C587 /* test002_testServiceCode2.xml */, + 0894254324637F0E0065C587 /* test003_ServiceCode4.xml */, + 0841824E240706DF00371637 /* Info.plist */, + ); + path = OSXProxyTests; + sourceTree = ""; + }; + 088E619B2448BE01007C4AE5 /* OSXProxyUITests */ = { + isa = PBXGroup; + children = ( + 088E62A82448E3D2007C4AE5 /* OSXProxyUITests.m */, + 088E619E2448BE01007C4AE5 /* Info.plist */, + ); + path = OSXProxyUITests; + sourceTree = ""; + }; 0D15B1801C5DA681001A0EEF /* CustomViews */ = { isa = PBXGroup; children = ( @@ -262,17 +330,19 @@ 9C93FD2E198ADBD700227E47 = { isa = PBXGroup; children = ( + 0DB105911DBC2E30004289E7 /* Settings.plist */, 0DB4CA8B20D7793500FFFD23 /* OSXProxy-Prefix.pch */, 0DB4CA6B20D7768100FFFD23 /* RoleMapping.plist */, 0DB105E51DBC3497004289E7 /* CustomWindowController.xib */, 0DB105E71DBC3497004289E7 /* MainMenu.xib */, 0DB105951DBC2FDC004289E7 /* Images.xcassets */, - 0DB105911DBC2E30004289E7 /* Settings.plist */, 0DB1058E1DBC2E18004289E7 /* AppDelegate.m */, 0DB1058F1DBC2E18004289E7 /* AppDelegate.h */, 0DAF71341DB825A5002BE0A1 /* Connection */, 0D6C19831DB70E55004DFB3F /* AppleXMLSerializer */, 9C93FD40198ADBD700227E47 /* OSXProxy */, + 0841824B240706DF00371637 /* OSXProxyTests */, + 088E619B2448BE01007C4AE5 /* OSXProxyUITests */, 9C93FD39198ADBD700227E47 /* Frameworks */, 9C93FD38198ADBD700227E47 /* Products */, ); @@ -282,6 +352,8 @@ isa = PBXGroup; children = ( 9C93FD37198ADBD700227E47 /* OSXProxy.app */, + 0841824A240706DF00371637 /* OSXProxyTests.xctest */, + 088E619A2448BE01007C4AE5 /* OSXProxyUITests.xctest */, ); name = Products; sourceTree = ""; @@ -352,6 +424,42 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 08418249240706DF00371637 /* OSXProxyTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 08418251240706DF00371637 /* Build configuration list for PBXNativeTarget "OSXProxyTests" */; + buildPhases = ( + 08418246240706DF00371637 /* Sources */, + 08418247240706DF00371637 /* Frameworks */, + 08418248240706DF00371637 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 08418250240706DF00371637 /* PBXTargetDependency */, + ); + name = OSXProxyTests; + productName = OSXProxyTests; + productReference = 0841824A240706DF00371637 /* OSXProxyTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 088E61992448BE01007C4AE5 /* OSXProxyUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 088E61A12448BE01007C4AE5 /* Build configuration list for PBXNativeTarget "OSXProxyUITests" */; + buildPhases = ( + 088E61962448BE01007C4AE5 /* Sources */, + 088E61972448BE01007C4AE5 /* Frameworks */, + 088E61982448BE01007C4AE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 088E61A02448BE01007C4AE5 /* PBXTargetDependency */, + ); + name = OSXProxyUITests; + productName = OSXProxyUITests; + productReference = 088E619A2448BE01007C4AE5 /* OSXProxyUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; 9C93FD36198ADBD700227E47 /* OSXProxy */ = { isa = PBXNativeTarget; buildConfigurationList = 9C93FD68198ADBD700227E47 /* Build configuration list for PBXNativeTarget "OSXProxy" */; @@ -375,12 +483,12 @@ 9C93FD2F198ADBD700227E47 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0930; - ORGANIZATIONNAME = "Stony Brook University"; + LastUpgradeCheck = 1110; + ORGANIZATIONNAME = "University of North Carolina"; }; buildConfigurationList = 9C93FD32198ADBD700227E47 /* Build configuration list for PBXProject "OSXProxy" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -392,11 +500,30 @@ projectRoot = ""; targets = ( 9C93FD36198ADBD700227E47 /* OSXProxy */, + 08418249240706DF00371637 /* OSXProxyTests */, + 088E61992448BE01007C4AE5 /* OSXProxyUITests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 08418248240706DF00371637 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0894254524637F0E0065C587 /* test002_testServiceCode2.xml in Resources */, + 0894254424637F0E0065C587 /* test001_ServiceCode2_empty.xml in Resources */, + 0894254624637F0E0065C587 /* test003_ServiceCode4.xml in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 088E61982448BE01007C4AE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 9C93FD35198ADBD700227E47 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -423,6 +550,22 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 08418246240706DF00371637 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0841824D240706DF00371637 /* OSXProxyTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 088E61962448BE01007C4AE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 088E62A92448E3D2007C4AE5 /* OSXProxyUITests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 9C93FD33198ADBD700227E47 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -463,6 +606,19 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 08418250240706DF00371637 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 9C93FD36198ADBD700227E47 /* OSXProxy */; + targetProxy = 0841824F240706DF00371637 /* PBXContainerItemProxy */; + }; + 088E61A02448BE01007C4AE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 9C93FD36198ADBD700227E47 /* OSXProxy */; + targetProxy = 088E619F2448BE01007C4AE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 0DB105E51DBC3497004289E7 /* CustomWindowController.xib */ = { isa = PBXVariantGroup; @@ -499,10 +655,122 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 08418252240706DF00371637 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = ""; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = OSXProxyTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = OSXProxyTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OSXProxy.app/Contents/MacOS/OSXProxy"; + }; + name = Debug; + }; + 08418253240706DF00371637 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = OSXProxyTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = OSXProxyTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OSXProxy.app/Contents/MacOS/OSXProxy"; + }; + name = Release; + }; + 088E61A22448BE01007C4AE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = ""; + GCC_C_LANGUAGE_STANDARD = gnu11; + HEADER_SEARCH_PATHS = /usr/include/libxml2; + INFOPLIST_FILE = OSXProxyUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/OSXProxyUITests", + ); + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = unc.OSXProxyUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_TARGET_NAME = OSXProxy; + }; + name = Debug; + }; + 088E61A32448BE01007C4AE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + HEADER_SEARCH_PATHS = /usr/include/libxml2; + INFOPLIST_FILE = OSXProxyUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/OSXProxyUITests", + ); + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = unc.OSXProxyUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_TARGET_NAME = OSXProxy; + }; + name = Release; + }; 9C93FD66198ADBD700227E47 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; + ALWAYS_SEARCH_USER_PATHS = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -526,6 +794,7 @@ CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -545,7 +814,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.14; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; }; @@ -554,7 +823,7 @@ 9C93FD67198ADBD700227E47 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; + ALWAYS_SEARCH_USER_PATHS = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -591,7 +860,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.14; SDKROOT = macosx; }; name = Release; @@ -601,13 +870,14 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = ""; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "OSXProxy/OSXProxy-Prefix.pch"; HEADER_SEARCH_PATHS = /usr/include/libxml2; INFOPLIST_FILE = "OSXProxy/OSXProxy-Info.plist"; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.10; OTHER_LDFLAGS = "-lxml2"; - PRODUCT_BUNDLE_IDENTIFIER = "SBU.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_BUNDLE_IDENTIFIER = edu.unc.OSXProxy; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -622,9 +892,9 @@ GCC_PREFIX_HEADER = "OSXProxy/OSXProxy-Prefix.pch"; HEADER_SEARCH_PATHS = /usr/include/libxml2; INFOPLIST_FILE = "OSXProxy/OSXProxy-Info.plist"; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.10; OTHER_LDFLAGS = "-lxml2"; - PRODUCT_BUNDLE_IDENTIFIER = "SBU.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_BUNDLE_IDENTIFIER = edu.unc.OSXProxy; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -633,6 +903,24 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 08418251240706DF00371637 /* Build configuration list for PBXNativeTarget "OSXProxyTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 08418252240706DF00371637 /* Debug */, + 08418253240706DF00371637 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 088E61A12448BE01007C4AE5 /* Build configuration list for PBXNativeTarget "OSXProxyUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 088E61A22448BE01007C4AE5 /* Debug */, + 088E61A32448BE01007C4AE5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 9C93FD32198ADBD700227E47 /* Build configuration list for PBXProject "OSXProxy" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/osxproxy/OSXProxy.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/osxproxy/OSXProxy.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/osxproxy/OSXProxy.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/osxproxy/OSXProxy.xcodeproj/xcshareddata/xcschemes/OSXProxy.xcscheme b/osxproxy/OSXProxy.xcodeproj/xcshareddata/xcschemes/OSXProxy.xcscheme new file mode 100644 index 0000000..3ca0f0f --- /dev/null +++ b/osxproxy/OSXProxy.xcodeproj/xcshareddata/xcschemes/OSXProxy.xcscheme @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/osxproxy/OSXProxy/AppDelegate.h b/osxproxy/OSXProxy/AppDelegate.h index 49d7914..4dc6e9d 100644 --- a/osxproxy/OSXProxy/AppDelegate.h +++ b/osxproxy/OSXProxy/AppDelegate.h @@ -25,6 +25,7 @@ */ #import +#import "Sinter.h" @class Model; @@ -56,6 +57,7 @@ - (void) selectRemoteProcess:(id) process_id; - (void) disconnect; +- (void) takeActionForXML:(Sinter *) sinter; - (IBAction) connect:(id) sender; - (IBAction) fetchRemoteProcesses:(id) sender; - (IBAction) disconnectButtonClicked:(id) sender; diff --git a/osxproxy/OSXProxy/OSXProxy-Info.plist b/osxproxy/OSXProxy/OSXProxy-Info.plist index b42d0f8..a11fad4 100644 --- a/osxproxy/OSXProxy/OSXProxy-Info.plist +++ b/osxproxy/OSXProxy/OSXProxy-Info.plist @@ -9,7 +9,7 @@ CFBundleIconFile CFBundleIdentifier - SBU.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/osxproxy/OSXProxy/Settings.plist b/osxproxy/OSXProxy/Settings.plist index 137a5b7..89789fd 100644 --- a/osxproxy/OSXProxy/Settings.plist +++ b/osxproxy/OSXProxy/Settings.plist @@ -6,5 +6,9 @@ 6832 server_ip 192.168.28.128 + xml_logfolder + + jenkins_output_dir + /Users/jenkins/workspace/sinter-mac/testoutput diff --git a/osxproxy/OSXProxyTests/OSXProxyTests-Info.plist b/osxproxy/OSXProxyTests/Info.plist similarity index 91% rename from osxproxy/OSXProxyTests/OSXProxyTests-Info.plist rename to osxproxy/OSXProxyTests/Info.plist index 7e0a773..169b6f7 100644 --- a/osxproxy/OSXProxyTests/OSXProxyTests-Info.plist +++ b/osxproxy/OSXProxyTests/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - SBU.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType diff --git a/osxproxy/OSXProxyTests/OSXProxy.m b/osxproxy/OSXProxyTests/OSXProxy.m deleted file mode 100644 index 9e5a0bb..0000000 --- a/osxproxy/OSXProxyTests/OSXProxy.m +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (C) 2014--2018 Stony Brook University - Copyright (C) 2016--2018 The University of North Carolina at Chapel Hill - - This file is part of the Sinter Remote Desktop System. - - Sinter is dual-licensed, available under a commercial license or - for free subject to the LGPL. - - Sinter is free software: you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. Sinter is distributed in the - hope that it will be useful, but WITHOUT ANY WARRANTY; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the GNU Lesser General Public License for more details. You - should have received a copy of the GNU Lesser General Public License along - with this program. If not, see . -*/ - -/* - NVRDPTests.m - NVRDPTests - - Created by Syed Masum Billah on 7/31/14. -*/ - -#import - -@interface NVRDPTests : XCTestCase - -@end - -@implementation NVRDPTests - -- (void)setUp -{ - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown -{ - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; -} - -- (void)testExample -{ - XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); -} - -@end diff --git a/osxproxy/OSXProxyTests/OSXProxyTests.m b/osxproxy/OSXProxyTests/OSXProxyTests.m index 58b7e4b..771ccde 100644 --- a/osxproxy/OSXProxyTests/OSXProxyTests.m +++ b/osxproxy/OSXProxyTests/OSXProxyTests.m @@ -1,30 +1,17 @@ -/* Copyright (C) 2014--2018 Stony Brook University - Copyright (C) 2016--2018 The University of North Carolina at Chapel Hill - - This file is part of the Sinter Remote Desktop System. - - Sinter is dual-licensed, available under a commercial license or - for free subject to the LGPL. - - Sinter is free software: you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. Sinter is distributed in the - hope that it will be useful, but WITHOUT ANY WARRANTY; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the GNU Lesser General Public License for more details. You - should have received a copy of the GNU Lesser General Public License along - with this program. If not, see . -*/ - -/* - NVRDPTests.m - NVRDPTests - - Created by Syed Masum Billah on 7/31/14. -*/ +// +// OSXProxyTests.m +// OSXProxyTests +// +// Created by Erica Fu on 2/26/20. +// Copyright © 2020 UNC Chapel Hill. All rights reserved. +// #import +#import "Serializer.h" +#import "Sinter.h" +#import "AppDelegate.h" +#import "Model.h" +#import "CustomWindowController.h" @interface OSXProxyTests : XCTestCase @@ -32,21 +19,75 @@ @interface OSXProxyTests : XCTestCase @implementation OSXProxyTests -- (void)setUp -{ - [super setUp]; +AppDelegate * appDelegate; +- (void)setUp { // Put setup code here. This method is called before the invocation of each test method in the class. + appDelegate = (AppDelegate * )[NSApp delegate]; } -- (void)tearDown -{ +- (void)tearDown { // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; } -- (void)testExample -{ - XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); +- (Sinter *)getSinterFromInputFile: (NSString *) filename { + NSError * error = NULL; + NSString * incoming_data = [NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:&error]; + return [Serializer xmlToObject:incoming_data]; +} + + +- (void)test001_ServiceCode2_empty { + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSString *inputfile = [bundle pathForResource:@"test001_ServiceCode2_empty" ofType:@"xml"]; + Sinter * sinter = [self getSinterFromInputFile:inputfile]; + XCTAssertNotNil(sinter); + [appDelegate takeActionForXML:sinter]; + + // the rendering code is wrapped in dispatch_async() in initWithWindowNibName() + // run mainRunLoop to let it call the async block + [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; + + // No process is listed, nothing really happens. + XCTAssertTrue(appDelegate.remoteProcesses == nil || [appDelegate.remoteProcesses count] == 0); +} + +- (void)test002_testServiceCode2 { + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSString *inputfile = [bundle pathForResource:@"test002_testServiceCode2" ofType:@"xml"]; + Sinter * sinter = [self getSinterFromInputFile:inputfile]; + XCTAssertNotNil(sinter); + NSUInteger n_processes = [sinter.entities count]; + [appDelegate takeActionForXML:sinter]; + + // the rendering code is wrapped in dispatch_async() in initWithWindowNibName() + // run mainRunLoop to let it call the async block + [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; + + XCTAssertTrue([appDelegate.remoteProcesses count] == n_processes); + NSLog(@"name = %@", ((Model*)(appDelegate.remoteProcesses[0])).name); //process_id, unique_id +} + +- (void)test003_ServiceCode4 { + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSString *inputfile = [bundle pathForResource:@"test003_ServiceCode4" ofType:@"xml"]; + Sinter * sinter = [self getSinterFromInputFile:inputfile]; + XCTAssertNotNil(sinter); + [appDelegate takeActionForXML:sinter]; + + // the rendering code is wrapped in dispatch_async() in initWithWindowNibName() + // run mainRunLoop to let it call the async block + [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; + + NSMutableArray* renderedWindows = [appDelegate.remoteWindowControllers objectForKey:sinter.header.process_id]; + XCTAssertTrue([renderedWindows count] >= 1); + CustomWindowController * renderWindow = renderedWindows[0]; + XCTAssertTrue([sinter.entity.unique_id isEqualToString:renderWindow.rmUiRoot.unique_id]); + NSView* view = [renderWindow.window contentView]; + XCTAssertNotNil(view); + + // more to do: + // check MENU: CustomWindowController->remoteMenu + // check App DOM: [renderWindow.window contentView] } @end diff --git a/osxproxy/OSXProxyTests/en.lproj/InfoPlist.strings b/osxproxy/OSXProxyTests/en.lproj/InfoPlist.strings deleted file mode 100644 index 477b28f..0000000 --- a/osxproxy/OSXProxyTests/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/osxproxy/OSXProxyTests/test001_ServiceCode2_empty.xml b/osxproxy/OSXProxyTests/test001_ServiceCode2_empty.xml new file mode 100644 index 0000000..3951399 --- /dev/null +++ b/osxproxy/OSXProxyTests/test001_ServiceCode2_empty.xml @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/osxproxy/OSXProxyTests/test002_testServiceCode2.xml b/osxproxy/OSXProxyTests/test002_testServiceCode2.xml new file mode 100644 index 0000000..ba97120 --- /dev/null +++ b/osxproxy/OSXProxyTests/test002_testServiceCode2.xml @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/osxproxy/OSXProxyTests/test003_ServiceCode4.xml b/osxproxy/OSXProxyTests/test003_ServiceCode4.xml new file mode 100644 index 0000000..5239be2 --- /dev/null +++ b/osxproxy/OSXProxyTests/test003_ServiceCode4.xml @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/osxproxy/OSXProxyUITests/Info.plist b/osxproxy/OSXProxyUITests/Info.plist new file mode 100644 index 0000000..64d65ca --- /dev/null +++ b/osxproxy/OSXProxyUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/osxproxy/OSXProxyUITests/OSXProxyUITests.m b/osxproxy/OSXProxyUITests/OSXProxyUITests.m new file mode 100644 index 0000000..b0353e4 --- /dev/null +++ b/osxproxy/OSXProxyUITests/OSXProxyUITests.m @@ -0,0 +1,75 @@ +// +// OSXProxyUITests.m +// OSXProxyUITests +// +// Created by Erica Fu on 4/16/20. +// Copyright © 2020 Stony Brook University. All rights reserved. +// + +#import + +/* +#import +#import +#import +#import +#import +#import "Serializer.h" +#import "Sinter.h" +#import "AppDelegate.h" +#import "Model.h" + */ + + +@interface OSXProxyUITests : XCTestCase + +@end + +@implementation OSXProxyUITests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + self.continueAfterFailure = NO; + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +/* +- (void)testLaunchPerformance { + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + // This measures how long it takes to launch your application. + [self measureWithMetrics:@[XCTOSSignpostMetric.applicationLaunchMetric] block:^{ + [[[XCUIApplication alloc] init] launch]; + }]; + } +} + */ + + +- (void)testMainUI { + // UI tests must launch the application that they test. + XCUIApplication *app = [[XCUIApplication alloc] init]; + app.launchEnvironment = @{@"isUITest": @YES}; + [app launch]; + + // Use recording to get started writing UI tests. + XCUIElement *remoteDesktopWindow = [[XCUIApplication alloc] init].windows[@"Remote Desktop"]; + XCUIElement *connectButton = remoteDesktopWindow.buttons[@"Connect"]; + XCUIElement *disconnectButton = remoteDesktopWindow.buttons[@"Disconnect"]; + + [connectButton click]; + XCTAssertTrue(connectButton.enabled == false); + XCTAssertTrue(disconnectButton.enabled == true); + + [disconnectButton click]; + XCTAssertTrue(connectButton.enabled == true); + XCTAssertTrue(disconnectButton.enabled == false); +} + +@end diff --git a/osxscraper/OSXScraper.xcodeproj/project.pbxproj b/osxscraper/OSXScraper.xcodeproj/project.pbxproj index 7f818a0..7061365 100644 --- a/osxscraper/OSXScraper.xcodeproj/project.pbxproj +++ b/osxscraper/OSXScraper.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 08172FA42317198C00897851 /* osxsinter.p12 in Resources */ = {isa = PBXBuildFile; fileRef = 08172FA32317198B00897851 /* osxsinter.p12 */; }; 08172FA6231724DA00897851 /* Settings.plist in Resources */ = {isa = PBXBuildFile; fileRef = 08172FA5231724DA00897851 /* Settings.plist */; }; + 084181B82406D5E300371637 /* Sinter.h in Sources */ = {isa = PBXBuildFile; fileRef = 0DB4CA5920D75B4900FFFD23 /* Sinter.h */; }; 08791EB622331CB2009EB201 /* Word.m in Sources */ = {isa = PBXBuildFile; fileRef = 08791EB322331CB2009EB201 /* Word.m */; }; 08791EB722331CB2009EB201 /* Params.m in Sources */ = {isa = PBXBuildFile; fileRef = 08791EB522331CB2009EB201 /* Params.m */; }; 08791EC022331EA3009EB201 /* XMLTags.m in Sources */ = {isa = PBXBuildFile; fileRef = 08791EBE22331EA2009EB201 /* XMLTags.m */; }; @@ -220,8 +221,8 @@ 9CFA677C1AA01865007E84ED /* OSXScraper */ = { isa = PBXGroup; children = ( - 9CFE595A1BCB01AD00BEAC79 /* AccessibilityDefinitions.plist */, 08172FA5231724DA00897851 /* Settings.plist */, + 9CFE595A1BCB01AD00BEAC79 /* AccessibilityDefinitions.plist */, 9CFE59551BCB00D100BEAC79 /* documentation.rtf */, 9CFE59561BCB00D100BEAC79 /* AccAPI.h */, 9CFE59571BCB00D100BEAC79 /* AccAPI.m */, @@ -329,6 +330,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -401,6 +403,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 084181B82406D5E300371637 /* Sinter.h in Sources */, 9CFA67A11AA01865007E84ED /* OSXScraperTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -557,10 +560,10 @@ GCC_PREFIX_HEADER = "OSXScraper/OSXScraper-Prefix.pch"; HEADER_SEARCH_PATHS = /usr/include/libxml2; INFOPLIST_FILE = "$(SRCROOT)/OSXScraper/OSXScraper-Info.plist"; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-lxml2"; - PRODUCT_BUNDLE_IDENTIFIER = SBU.OSXScraper; + PRODUCT_BUNDLE_IDENTIFIER = edu.unc.OSXScraper; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -575,10 +578,10 @@ GCC_PREFIX_HEADER = "OSXScraper/OSXScraper-Prefix.pch"; HEADER_SEARCH_PATHS = /usr/include/libxml2; INFOPLIST_FILE = "$(SRCROOT)/OSXScraper/OSXScraper-Info.plist"; - MACOSX_DEPLOYMENT_TARGET = ""; + MACOSX_DEPLOYMENT_TARGET = 10.10; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-lxml2"; - PRODUCT_BUNDLE_IDENTIFIER = "SBU.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_BUNDLE_IDENTIFIER = edu.unc.OSXScraper; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/osxscraper/OSXScraper.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/osxscraper/OSXScraper.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/osxscraper/OSXScraper.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/osxscraper/OSXScraper/AccAPI.h b/osxscraper/OSXScraper/AccAPI.h index a117c11..bccc67c 100644 --- a/osxscraper/OSXScraper/AccAPI.h +++ b/osxscraper/OSXScraper/AccAPI.h @@ -30,9 +30,10 @@ @interface AccAPI : NSObject + (void) initialize; ++ (BOOL) isUnitTesting; + (NSArray *) getAllProcessesIDs; + (Entity *) getEntityForApp:(pid_t) pid; - ++ (void) addValidApp: (NSString*) appName; + (Sinter *) getListOfApplications; + (Sinter *) getDomOf:(pid_t) pid andReturnRef:(AXUIElementRef*) elemRef diff --git a/osxscraper/OSXScraper/AccAPI.m b/osxscraper/OSXScraper/AccAPI.m index c8759be..af85d9b 100644 --- a/osxscraper/OSXScraper/AccAPI.m +++ b/osxscraper/OSXScraper/AccAPI.m @@ -36,7 +36,7 @@ static NSDictionary * roleMappings; -static NSArray* valid_apps; +static NSMutableArray* valid_apps; @implementation AccAPI @@ -47,10 +47,14 @@ + (void) initialize { valid_apps = [settings objectForKey:@"support_apps"]; } ++ (BOOL) isUnitTesting { + NSDictionary* environment = [[NSProcessInfo processInfo] environment]; + return (environment[@"XCTestConfigurationFilePath"] != nil); +} + + (NSArray *) getAllProcessesIDs { CFArrayRef appList = CGWindowListCopyWindowInfo((kCGWindowListOptionOnScreenOnly), kCGNullWindowID); int num_process = (int) CFArrayGetCount(appList); - NSLog(@"Process Count = %i", num_process); NSMutableArray * processes = [[NSMutableArray alloc] initWithCapacity:num_process]; for (NSMutableDictionary* win in (__bridge NSArray*) appList){ @@ -89,6 +93,13 @@ + (Entity *) getEntityForApp:(pid_t) pid { return entity; } ++ (void) addValidApp: (NSString*) appName { + if(![valid_apps containsObject:appName]){ + [valid_apps addObject:appName]; + NSLog(@"%s valid apps: %@", __PRETTY_FUNCTION__, valid_apps); + } +} + // ls command + (Sinter *) getListOfApplications { Sinter * sinter = [[Sinter alloc] initWithEntities]; @@ -96,14 +107,19 @@ + (Sinter *) getListOfApplications { sinter.header.sub_code = [serviceCodes objectForKey:STRLsRes]; NSArray * processes = [self getAllProcessesIDs]; + + int nProcessAbleToSee = 0; for ( NSNumber * process_id in processes){ Entity * e = [self getEntityForApp: (pid_t) [process_id integerValue]]; if(e != nil){ - if([valid_apps containsObject:e.name]) + nProcessAbleToSee ++; + if ([AccAPI isUnitTesting]) NSLog(@"%s ableToSee: %@", __PRETTY_FUNCTION__, e.name); + if([valid_apps containsObject:e.name]) { [sinter.entities addObject:e]; + } } } - + if ([AccAPI isUnitTesting]) NSLog(@"%s nProcessAbleToSee = %i", __PRETTY_FUNCTION__, nProcessAbleToSee); return sinter; } diff --git a/osxscraper/OSXScraper/Scraper.h b/osxscraper/OSXScraper/Scraper.h index 6733191..20ca0c7 100644 --- a/osxscraper/OSXScraper/Scraper.h +++ b/osxscraper/OSXScraper/Scraper.h @@ -36,9 +36,7 @@ @property (nonatomic, strong ) NSMutableDictionary* appCache; @property (nonatomic, strong ) NSMutableDictionary* appObservers; - - - (id) initWithId:(int) identifier andClientHandler:(ClientHandler *) clientHandler; - +- (Sinter *) execute: (Sinter *) cmdSinter; @end diff --git a/osxscraper/OSXScraper/Scraper.m b/osxscraper/OSXScraper/Scraper.m index ba6e106..c6f3030 100644 --- a/osxscraper/OSXScraper/Scraper.m +++ b/osxscraper/OSXScraper/Scraper.m @@ -51,6 +51,9 @@ - (id) initWithId:(int) identifier andClientHandler:(ClientHandler *) clientHand [self setIdentifier:identifier]; [self setClientHandler:clientHandler]; _isPasscodeVerified = false; + if ([AccAPI isUnitTesting]){ + _isPasscodeVerified = true; + } appCache = [[NSMutableDictionary alloc] init]; appObservers = [[NSMutableDictionary alloc] init]; @@ -103,7 +106,7 @@ - (void)applicationTerminated:(NSNotification *)notification } } -- (void) execute: (Sinter *) cmdSinter { +- (Sinter *) execute: (Sinter *) cmdSinter { NSNumber * service_code = cmdSinter.header.service_code; Sinter * sinterToSend = nil; if ([service_code isEqualToNumber: [serviceCodes objectForKey:STRVerifyPasscode]]) { @@ -162,10 +165,16 @@ - (void) execute: (Sinter *) cmdSinter { } + if ([AccAPI isUnitTesting]){ + //if unit-testing, just return. + return sinterToSend; + } + // send sinter response if (sinterToSend) { [_clientHandler sendSinter:sinterToSend]; } + return nil; } @@ -298,7 +307,15 @@ - (BOOL) registerObserverFor:(pid_t) pid forElementRef:(AXUIElementRef) appRef { } - (bool) checkAccessibilityAPI { - NSDictionary *options = @{(__bridge id) kAXTrustedCheckOptionPrompt: @YES }; + NSDictionary *options; + if ([AccAPI isUnitTesting]){ + // do not user-prompt when autotesting + options = @{(__bridge id) kAXTrustedCheckOptionPrompt: @NO }; + } + else { + options = @{(__bridge id) kAXTrustedCheckOptionPrompt: @YES }; + } + if(!AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)options)){ NSLog(@"Accessibility API not enabled"); }else{ diff --git a/osxscraper/OSXScraper/Settings.plist b/osxscraper/OSXScraper/Settings.plist index 4c9e48c..1f6b5c2 100644 --- a/osxscraper/OSXScraper/Settings.plist +++ b/osxscraper/OSXScraper/Settings.plist @@ -14,5 +14,9 @@ osxsinter.p12 certificate_passcode 123456 + xml_logfolder + + jenkins_output_dir + /Users/jenkins/workspace/sinter-mac/testoutput diff --git a/osxscraper/OSXScraperTests/OSXScraperTests.m b/osxscraper/OSXScraperTests/OSXScraperTests.m index 180e445..5562312 100644 --- a/osxscraper/OSXScraperTests/OSXScraperTests.m +++ b/osxscraper/OSXScraperTests/OSXScraperTests.m @@ -1,5 +1,5 @@ /* Copyright (C) 2014--2018 Stony Brook University - Copyright (C) 2016--2018 The University of North Carolina at Chapel Hill + Copyright (C) 2016--2020 The University of North Carolina at Chapel Hill This file is part of the Sinter Remote Desktop System. @@ -25,6 +25,14 @@ */ #import +#import "AccAPI.h" +#import "Entity.h" +#import "Sinter.h" +#import "Config.h" +#import "XMLTags.h" +#import "Scraper.h" +#import "Serializer.h" + @interface OSXScrapperTests : XCTestCase @@ -32,21 +40,149 @@ @interface OSXScrapperTests : XCTestCase @implementation OSXScrapperTests +NSString * OSXScraperName; +Scraper * scraper; +NSTask * CalcTask; + - (void)setUp { [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. + + /* Adding self name to ValidApps and we will scraper self for the test */ + OSXScraperName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(id)kCFBundleNameKey]; + [AccAPI addValidApp:OSXScraperName]; + + /* create a scraper with no connection */ + scraper = [[Scraper alloc] initWithId:1 andClientHandler:nil] ; + + NSError *err; + CalcTask = [[NSTask alloc] init]; + [CalcTask setLaunchPath:@"/Applications/Calculator.app/Contents/MacOS/Calculator"]; + [CalcTask setArguments:[NSArray arrayWithObjects:@"/bin/bash", nil]]; + [CalcTask launchAndReturnError:&err]; + NSLog(@"err: %@", err.localizedDescription); } - (void)tearDown { // Put teardown code here. This method is called after the invocation of each test method in the class. [super tearDown]; + [CalcTask terminate]; + +} + +- (int) exportSinter:(Sinter *) sinter { + NSString * message = [Serializer objectToXml:sinter]; + NSDictionary * instanceSetting = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"plist"]]; + NSString * logfolder = [instanceSetting objectForKey:@"jenkins_output_dir"]; + NSFileManager *fileManager = [[NSFileManager alloc] init]; + BOOL isDir; + if ([fileManager fileExistsAtPath:logfolder isDirectory:&isDir] && isDir){ + NSString * filename = [NSString stringWithFormat:@"%@/%@.xml", logfolder, self.name]; + NSError * error = NULL; + if([message writeToFile:filename atomically:NO encoding:NSUTF8StringEncoding error:&error]) + { + NSLog( @"xml saving to %@", filename); + return 0; + } + } + return -1; +} + +- (void) test001_LS_Self +{ + //test 'list of applications', should see itself (OSXScraper) + Sinter * sinterInput = [[Sinter alloc] initWithServiceCode:[serviceCodes objectForKey:STRLsReq]]; + Sinter * sinterOutput = [scraper execute:sinterInput]; + XCTAssertNotNil(sinterOutput); + XCTAssertTrue([sinterOutput.header.service_code isEqualToNumber: [serviceCodes objectForKey:STRLsRes]]); + XCTAssertTrue(sinterOutput.entities.count >= 1); + + BOOL bFoundSelf = NO; + NSLog(@"%s entities count: %ld", __PRETTY_FUNCTION__, [sinterOutput.entities count]); + for (Entity* e in sinterOutput.entities){ + NSLog(@"%s %@, %@", __PRETTY_FUNCTION__, e.name, e.process_id); + if ([e.name isEqualToString:OSXScraperName]){ + bFoundSelf = YES; + } + } + XCTAssertTrue(bFoundSelf); } -- (void)testExample +- (void) test001_LS_Calc { - XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); + //test 'list of applications', should see Calculator + Sinter * sinterInput = [[Sinter alloc] initWithServiceCode:[serviceCodes objectForKey:STRLsReq]]; + Sinter * sinterOutput = [scraper execute:sinterInput]; + XCTAssertNotNil(sinterOutput); + XCTAssertTrue([sinterOutput.header.service_code isEqualToNumber: [serviceCodes objectForKey:STRLsRes]]); + XCTAssertTrue(sinterOutput.entities.count >= 1); + + BOOL bFound = NO; + NSLog(@"%s entities count: %ld", __PRETTY_FUNCTION__, [sinterOutput.entities count]); + for (Entity* e in sinterOutput.entities){ + NSLog(@"%s %@, %@", __PRETTY_FUNCTION__, e.name, e.process_id); + if ([e.name isEqualToString:@"Calculator"]){ + bFound = YES; + } + } + XCTAssertTrue(bFound); +} + +- (void) test002_LongLS_Self +{ + // first get the process_id of itself, then test long LS (scrape it and output a response sinter) + Sinter * sinterOutput = [AccAPI getListOfApplications]; + NSString* process_id; + for (Entity* e in sinterOutput.entities){ + if ([e.name isEqualToString:OSXScraperName]){ + NSLog(@"%s %@, %@", __PRETTY_FUNCTION__, e.name, e.process_id); + process_id = e.process_id; + break; + } + } + // create a sinterInput2 with process_id to test + Sinter * sinterInput2 = [[Sinter alloc] init]; + sinterInput2.header = [[Header alloc] initWithServiceCode:[serviceCodes objectForKey:STRLsLongReq] + subCode:[serviceCodes objectForKey:STRLsLongReq] + processId:process_id + parameters:nil]; + Sinter * sinterOutput2 = [scraper execute:sinterInput2]; + XCTAssertNotNil(sinterOutput2); + XCTAssertTrue([sinterOutput2.header.process_id isEqualToString:process_id]); + XCTAssertTrue([sinterOutput2.header.service_code isEqualToNumber: [serviceCodes objectForKey:STRLsLongRes]]); + XCTAssertNotNil(sinterOutput2.entity); + XCTAssertTrue([self exportSinter:sinterOutput2] == 0); +} + +- (void) test002_LongLS_Calc +{ + // first get the process_id of itself, then test long LS (scrape it and output a response sinter) + Sinter * sinterOutput = [AccAPI getListOfApplications]; + NSString* process_id; + for (Entity* e in sinterOutput.entities){ + if ([e.name isEqualToString:@"Calculator"]){ + NSLog(@"%s %@, %@", __PRETTY_FUNCTION__, e.name, e.process_id); + process_id = e.process_id; + break; + } + } + XCTAssertNotNil(process_id); + + // create a sinterInput2 with process_id to test + if (process_id != nil) { + Sinter * sinterInput2 = [[Sinter alloc] init]; + sinterInput2.header = [[Header alloc] initWithServiceCode:[serviceCodes objectForKey:STRLsLongReq] + subCode:[serviceCodes objectForKey:STRLsLongReq] + processId:process_id + parameters:nil]; + Sinter * sinterOutput2 = [scraper execute:sinterInput2]; + XCTAssertNotNil(sinterOutput2); + XCTAssertTrue([sinterOutput2.header.process_id isEqualToString:process_id]); + XCTAssertTrue([sinterOutput2.header.service_code isEqualToNumber: [serviceCodes objectForKey:STRLsLongRes]]); + XCTAssertNotNil(sinterOutput2.entity); + XCTAssertTrue([self exportSinter:sinterOutput2] == 0); + } } @end