From 1e963382ea529cad1d7867a1581bafbd4f55c200 Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Wed, 23 Oct 2024 11:45:25 -0400 Subject: [PATCH 01/14] [Vertex AI] Add test app for integration tests --- .../IntegrationTests/IntegrationTests.swift | 166 ++++++ .../VertexAITestApp.xcodeproj/project.pbxproj | 536 ++++++++++++++++++ .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 63 ++ .../Assets.xcassets/Contents.json | 6 + .../TestApp/VertexAITestApp/ContentView.swift | 31 + .../Preview Assets.xcassets/Contents.json | 6 + .../VertexAITestApp.entitlements | 10 + .../VertexAITestApp/VertexAITestApp.swift | 29 + 9 files changed, 858 insertions(+) create mode 100644 FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift create mode 100644 FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj/project.pbxproj create mode 100644 FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/Contents.json create mode 100644 FirebaseVertexAI/Tests/TestApp/VertexAITestApp/ContentView.swift create mode 100644 FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Preview Content/Preview Assets.xcassets/Contents.json create mode 100644 FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.entitlements create mode 100644 FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.swift diff --git a/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift b/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift new file mode 100644 index 00000000000..da6969d9a8f --- /dev/null +++ b/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift @@ -0,0 +1,166 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import FirebaseCore +import FirebaseVertexAI +import XCTest + +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *) +final class IntegrationTests: XCTestCase { + // Set temperature, topP and topK to lowest allowed values to make responses more deterministic. + let generationConfig = GenerationConfig( + temperature: 0.0, + topP: 0.0, + topK: 1, + responseMIMEType: "text/plain" + ) + let systemInstruction = ModelContent( + role: "system", + parts: "You are a friendly and helpful assistant." + ) + let safetySettings = [ + SafetySetting(harmCategory: .harassment, threshold: .blockLowAndAbove, method: .probability), + SafetySetting(harmCategory: .hateSpeech, threshold: .blockLowAndAbove, method: .severity), + SafetySetting(harmCategory: .sexuallyExplicit, threshold: .blockLowAndAbove), + SafetySetting(harmCategory: .dangerousContent, threshold: .blockLowAndAbove), + SafetySetting(harmCategory: .civicIntegrity, threshold: .blockLowAndAbove), + ] + + var vertex: VertexAI! + var model: GenerativeModel! + + override func setUp() async throws { + try XCTSkipIf(ProcessInfo.processInfo.environment["VertexAIRunIntegrationTests"] == nil, """ + Vertex AI integration tests skipped; to enable them, set the VertexAIRunIntegrationTests \ + environment variable in Xcode or CI jobs. + """) + + vertex = VertexAI.vertexAI() + model = vertex.generativeModel( + modelName: "gemini-1.5-flash", + generationConfig: generationConfig, + safetySettings: safetySettings, + tools: [], + toolConfig: .init(functionCallingConfig: .none()), + systemInstruction: systemInstruction + ) + } + + // MARK: - Generate Content + + func testGenerateContent() async throws { + let prompt = "Where is Google headquarters located? Answer with the city name only." + + let response = try await model.generateContent(prompt) + + let text = try XCTUnwrap(response.text).trimmingCharacters(in: .whitespacesAndNewlines) + XCTAssertEqual(text, "Mountain View") + } + + // MARK: - Count Tokens + + func testCountTokens_text() async throws { + let prompt = "Why is the sky blue?" + model = vertex.generativeModel( + modelName: "gemini-1.5-pro", + generationConfig: generationConfig, + safetySettings: [ + SafetySetting(harmCategory: .harassment, threshold: .blockLowAndAbove, method: .severity), + SafetySetting(harmCategory: .hateSpeech, threshold: .blockMediumAndAbove), + SafetySetting(harmCategory: .sexuallyExplicit, threshold: .blockOnlyHigh), + SafetySetting(harmCategory: .dangerousContent, threshold: .blockNone), + SafetySetting(harmCategory: .civicIntegrity, threshold: .off, method: .probability), + ], + toolConfig: .init(functionCallingConfig: .auto()), + systemInstruction: systemInstruction + ) + + let response = try await model.countTokens(prompt) + + XCTAssertEqual(response.totalTokens, 14) + XCTAssertEqual(response.totalBillableCharacters, 51) + } + + #if canImport(UIKit) + func testCountTokens_image_inlineData() async throws { + guard let image = UIImage(systemName: "cloud") else { + XCTFail("Image not found.") + return + } + + let response = try await model.countTokens(image) + + XCTAssertEqual(response.totalTokens, 266) + XCTAssertEqual(response.totalBillableCharacters, 35) + } + #endif // canImport(UIKit) + + func testCountTokens_image_fileData() async throws { + let fileData = FileDataPart( + uri: "gs://ios-opensource-samples.appspot.com/ios/public/blank.jpg", + mimeType: "image/jpeg" + ) + + let response = try await model.countTokens(fileData) + + XCTAssertEqual(response.totalTokens, 266) + XCTAssertEqual(response.totalBillableCharacters, 35) + } + + func testCountTokens_functionCalling() async throws { + let sumDeclaration = FunctionDeclaration( + name: "sum", + description: "Adds two integers.", + parameters: ["x": .integer(), "y": .integer()] + ) + model = vertex.generativeModel( + modelName: "gemini-1.5-flash", + tools: [.functionDeclarations([sumDeclaration])], + toolConfig: .init(functionCallingConfig: .any(allowedFunctionNames: ["sum"])) + ) + let prompt = "What is 10 + 32?" + let sumCall = FunctionCallPart(name: "sum", args: ["x": .number(10), "y": .number(32)]) + let sumResponse = FunctionResponsePart(name: "sum", response: ["result": .number(42)]) + + let response = try await model.countTokens([ + ModelContent(role: "user", parts: prompt), + ModelContent(role: "model", parts: sumCall), + ModelContent(role: "function", parts: sumResponse), + ]) + + XCTAssertEqual(response.totalTokens, 24) + XCTAssertEqual(response.totalBillableCharacters, 71) + } + + func testCountTokens_jsonSchema() async throws { + model = vertex.generativeModel( + modelName: "gemini-1.5-flash", + generationConfig: GenerationConfig( + responseMIMEType: "application/json", + responseSchema: Schema.object(properties: [ + "startDate": .string(format: .custom("date")), + "yearsSince": .integer(format: .custom("int16")), + "hoursSince": .integer(format: .int32), + "minutesSince": .integer(format: .int64), + ]) + ) + ) + let prompt = "It is 2050-01-01, how many years, hours and minutes since 2000-01-01?" + + let response = try await model.countTokens(prompt) + + XCTAssertEqual(response.totalTokens, 34) + XCTAssertEqual(response.totalBillableCharacters, 59) + } +} diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj/project.pbxproj b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..f10063c8646 --- /dev/null +++ b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj/project.pbxproj @@ -0,0 +1,536 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 60; + objects = { + +/* Begin PBXBuildFile section */ + 8661385C2CC943DD00F4B78E /* VertexAITestApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8661385B2CC943DD00F4B78E /* VertexAITestApp.swift */; }; + 8661385E2CC943DD00F4B78E /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8661385D2CC943DD00F4B78E /* ContentView.swift */; }; + 866138602CC943DE00F4B78E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8661385F2CC943DE00F4B78E /* Assets.xcassets */; }; + 866138642CC943DE00F4B78E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 866138632CC943DE00F4B78E /* Preview Assets.xcassets */; }; + 8661386E2CC943DE00F4B78E /* IntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8661386D2CC943DE00F4B78E /* IntegrationTests.swift */; }; + 8692F2982CC9477800539E8F /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 8692F2972CC9477800539E8F /* FirebaseAppCheck */; }; + 8692F29A2CC9477800539E8F /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 8692F2992CC9477800539E8F /* FirebaseAuth */; }; + 8692F29C2CC9477800539E8F /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 8692F29B2CC9477800539E8F /* FirebaseStorage */; }; + 8692F29E2CC9477800539E8F /* FirebaseVertexAI in Frameworks */ = {isa = PBXBuildFile; productRef = 8692F29D2CC9477800539E8F /* FirebaseVertexAI */; }; + 8692F2A02CC948C100539E8F /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8692F29F2CC948C100539E8F /* GoogleService-Info.plist */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 8661386A2CC943DE00F4B78E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 866138502CC943DD00F4B78E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 866138572CC943DD00F4B78E; + remoteInfo = VertexAITestApp; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 866138582CC943DD00F4B78E /* VertexAITestApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VertexAITestApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8661385B2CC943DD00F4B78E /* VertexAITestApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VertexAITestApp.swift; sourceTree = ""; }; + 8661385D2CC943DD00F4B78E /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 8661385F2CC943DE00F4B78E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 866138612CC943DE00F4B78E /* VertexAITestApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = VertexAITestApp.entitlements; sourceTree = ""; }; + 866138632CC943DE00F4B78E /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 866138692CC943DE00F4B78E /* IntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 8661386D2CC943DE00F4B78E /* IntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegrationTests.swift; sourceTree = ""; }; + 8692F29F2CC948C100539E8F /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 866138552CC943DD00F4B78E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8692F2982CC9477800539E8F /* FirebaseAppCheck in Frameworks */, + 8692F29E2CC9477800539E8F /* FirebaseVertexAI in Frameworks */, + 8692F29A2CC9477800539E8F /* FirebaseAuth in Frameworks */, + 8692F29C2CC9477800539E8F /* FirebaseStorage in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 866138662CC943DE00F4B78E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 8661384F2CC943DD00F4B78E = { + isa = PBXGroup; + children = ( + 8661385A2CC943DD00F4B78E /* VertexAITestApp */, + 8661386C2CC943DE00F4B78E /* IntegrationTests */, + 866138592CC943DD00F4B78E /* Products */, + ); + sourceTree = ""; + }; + 866138592CC943DD00F4B78E /* Products */ = { + isa = PBXGroup; + children = ( + 866138582CC943DD00F4B78E /* VertexAITestApp.app */, + 866138692CC943DE00F4B78E /* IntegrationTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 8661385A2CC943DD00F4B78E /* VertexAITestApp */ = { + isa = PBXGroup; + children = ( + 8661385B2CC943DD00F4B78E /* VertexAITestApp.swift */, + 8661385D2CC943DD00F4B78E /* ContentView.swift */, + 8661385F2CC943DE00F4B78E /* Assets.xcassets */, + 866138612CC943DE00F4B78E /* VertexAITestApp.entitlements */, + 8692F29F2CC948C100539E8F /* GoogleService-Info.plist */, + 866138622CC943DE00F4B78E /* Preview Content */, + ); + path = VertexAITestApp; + sourceTree = ""; + }; + 866138622CC943DE00F4B78E /* Preview Content */ = { + isa = PBXGroup; + children = ( + 866138632CC943DE00F4B78E /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 8661386C2CC943DE00F4B78E /* IntegrationTests */ = { + isa = PBXGroup; + children = ( + 8661386D2CC943DE00F4B78E /* IntegrationTests.swift */, + ); + path = IntegrationTests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 866138572CC943DD00F4B78E /* VertexAITestApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8661387D2CC943DE00F4B78E /* Build configuration list for PBXNativeTarget "VertexAITestApp" */; + buildPhases = ( + 866138542CC943DD00F4B78E /* Sources */, + 866138552CC943DD00F4B78E /* Frameworks */, + 866138562CC943DD00F4B78E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = VertexAITestApp; + packageProductDependencies = ( + 8692F2972CC9477800539E8F /* FirebaseAppCheck */, + 8692F2992CC9477800539E8F /* FirebaseAuth */, + 8692F29B2CC9477800539E8F /* FirebaseStorage */, + 8692F29D2CC9477800539E8F /* FirebaseVertexAI */, + ); + productName = VertexAITestApp; + productReference = 866138582CC943DD00F4B78E /* VertexAITestApp.app */; + productType = "com.apple.product-type.application"; + }; + 866138682CC943DE00F4B78E /* IntegrationTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 866138802CC943DE00F4B78E /* Build configuration list for PBXNativeTarget "IntegrationTests" */; + buildPhases = ( + 866138652CC943DE00F4B78E /* Sources */, + 866138662CC943DE00F4B78E /* Frameworks */, + 866138672CC943DE00F4B78E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8661386B2CC943DE00F4B78E /* PBXTargetDependency */, + ); + name = IntegrationTests; + productName = VertexAITestAppTests; + productReference = 866138692CC943DE00F4B78E /* IntegrationTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 866138502CC943DD00F4B78E /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1520; + LastUpgradeCheck = 1520; + TargetAttributes = { + 866138572CC943DD00F4B78E = { + CreatedOnToolsVersion = 15.2; + }; + 866138682CC943DE00F4B78E = { + CreatedOnToolsVersion = 15.2; + TestTargetID = 866138572CC943DD00F4B78E; + }; + }; + }; + buildConfigurationList = 866138532CC943DD00F4B78E /* Build configuration list for PBXProject "VertexAITestApp" */; + compatibilityVersion = "Xcode 15.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 8661384F2CC943DD00F4B78E; + packageReferences = ( + 8692F2962CC9477800539E8F /* XCLocalSwiftPackageReference "../../.." */, + ); + productRefGroup = 866138592CC943DD00F4B78E /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 866138572CC943DD00F4B78E /* VertexAITestApp */, + 866138682CC943DE00F4B78E /* IntegrationTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 866138562CC943DD00F4B78E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 866138642CC943DE00F4B78E /* Preview Assets.xcassets in Resources */, + 866138602CC943DE00F4B78E /* Assets.xcassets in Resources */, + 8692F2A02CC948C100539E8F /* GoogleService-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 866138672CC943DE00F4B78E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 866138542CC943DD00F4B78E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8661385E2CC943DD00F4B78E /* ContentView.swift in Sources */, + 8661385C2CC943DD00F4B78E /* VertexAITestApp.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 866138652CC943DE00F4B78E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8661386E2CC943DE00F4B78E /* IntegrationTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 8661386B2CC943DE00F4B78E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 866138572CC943DD00F4B78E /* VertexAITestApp */; + targetProxy = 8661386A2CC943DE00F4B78E /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 8661387B2CC943DE00F4B78E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 8661387C2CC943DE00F4B78E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SWIFT_COMPILATION_MODE = wholemodule; + }; + name = Release; + }; + 8661387E2CC943DE00F4B78E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = VertexAITestApp/VertexAITestApp.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"VertexAITestApp/Preview Content\""; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 17.2; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 14.2; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.VertexAITestApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 8661387F2CC943DE00F4B78E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = VertexAITestApp/VertexAITestApp.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"VertexAITestApp/Preview Content\""; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 17.2; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 14.2; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.VertexAITestApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 866138812CC943DE00F4B78E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.2; + MACOSX_DEPLOYMENT_TARGET = 14.2; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.VertexAITestAppTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VertexAITestApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/VertexAITestApp"; + }; + name = Debug; + }; + 866138822CC943DE00F4B78E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.2; + MACOSX_DEPLOYMENT_TARGET = 14.2; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.VertexAITestAppTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VertexAITestApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/VertexAITestApp"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 866138532CC943DD00F4B78E /* Build configuration list for PBXProject "VertexAITestApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8661387B2CC943DE00F4B78E /* Debug */, + 8661387C2CC943DE00F4B78E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8661387D2CC943DE00F4B78E /* Build configuration list for PBXNativeTarget "VertexAITestApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8661387E2CC943DE00F4B78E /* Debug */, + 8661387F2CC943DE00F4B78E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 866138802CC943DE00F4B78E /* Build configuration list for PBXNativeTarget "IntegrationTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 866138812CC943DE00F4B78E /* Debug */, + 866138822CC943DE00F4B78E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 8692F2962CC9477800539E8F /* XCLocalSwiftPackageReference "../../.." */ = { + isa = XCLocalSwiftPackageReference; + relativePath = ../../..; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 8692F2972CC9477800539E8F /* FirebaseAppCheck */ = { + isa = XCSwiftPackageProductDependency; + productName = FirebaseAppCheck; + }; + 8692F2992CC9477800539E8F /* FirebaseAuth */ = { + isa = XCSwiftPackageProductDependency; + productName = FirebaseAuth; + }; + 8692F29B2CC9477800539E8F /* FirebaseStorage */ = { + isa = XCSwiftPackageProductDependency; + productName = FirebaseStorage; + }; + 8692F29D2CC9477800539E8F /* FirebaseVertexAI */ = { + isa = XCSwiftPackageProductDependency; + productName = FirebaseVertexAI; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 866138502CC943DD00F4B78E /* Project object */; +} diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/AccentColor.colorset/Contents.json b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 00000000000..eb878970081 --- /dev/null +++ b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000000..532cd729c61 --- /dev/null +++ b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,63 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/Contents.json b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/Contents.json new file mode 100644 index 00000000000..73c00596a7f --- /dev/null +++ b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/ContentView.swift b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/ContentView.swift new file mode 100644 index 00000000000..52af5939455 --- /dev/null +++ b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/ContentView.swift @@ -0,0 +1,31 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import SwiftUI + +struct ContentView: View { + var body: some View { + VStack { + Image(systemName: "globe") + .imageScale(.large) + .foregroundStyle(.tint) + Text("Hello, world!") + } + .padding() + } +} + +#Preview { + ContentView() +} diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Preview Content/Preview Assets.xcassets/Contents.json b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 00000000000..73c00596a7f --- /dev/null +++ b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.entitlements b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.entitlements new file mode 100644 index 00000000000..ee95ab7e582 --- /dev/null +++ b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + + diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.swift b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.swift new file mode 100644 index 00000000000..43254830957 --- /dev/null +++ b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.swift @@ -0,0 +1,29 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import FirebaseCore +import SwiftUI + +@main +struct VertexAITestApp: App { + init() { + FirebaseApp.configure() + } + + var body: some Scene { + WindowGroup { + ContentView() + } + } +} From 34003e688e858f121a8876b8f8a17e174d1c5119 Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Thu, 24 Oct 2024 10:56:44 -0400 Subject: [PATCH 02/14] Add `spm-testapp-integration` job --- .github/workflows/vertexai.yml | 30 +++++++++++++++++++ .../Tests/TestApp/Resources/placeholder.txt | 1 + .../VertexAITestApp.xcodeproj/project.pbxproj | 16 +++++++--- scripts/build.sh | 9 ++++++ 4 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 FirebaseVertexAI/Tests/TestApp/Resources/placeholder.txt diff --git a/.github/workflows/vertexai.yml b/.github/workflows/vertexai.yml index 3d98ba70555..eaafc9195a5 100644 --- a/.github/workflows/vertexai.yml +++ b/.github/workflows/vertexai.yml @@ -125,6 +125,36 @@ jobs: retry_wait_seconds: 120 command: scripts/build.sh FirebaseVertexAIIntegration ${{ matrix.target }} spm + spm-testapp-integration: + strategy: + matrix: + target: [iOS] + os: [macos-15] + include: + - os: macos-15 + xcode: Xcode_16 + runs-on: ${{ matrix.os }} + needs: spm-package-resolved + env: + TEST_RUNNER_VertexAIRunIntegrationTests: 1 + FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1 + plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} + steps: + - uses: actions/checkout@v4 + - uses: actions/cache/restore@v4 + with: + path: .build + key: ${{needs.spm-package-resolved.outputs.cache_key}} + - name: Install Secret GoogleService-Info.plist + run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/vertexai-integration.plist.gpg \ + FirebaseVertexAI/Tests/TestApp/Resources/GoogleService-Info.plist "$plist_secret" + - name: Xcode + run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer + - name: Initialize xcodebuild + run: scripts/setup_spm_tests.sh + - name: Run IntegrationTests + run: scripts/build.sh VertexIntegration ${{ matrix.target }} + pod-lib-lint: # Don't run on private repo unless it is a PR. if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request' diff --git a/FirebaseVertexAI/Tests/TestApp/Resources/placeholder.txt b/FirebaseVertexAI/Tests/TestApp/Resources/placeholder.txt new file mode 100644 index 00000000000..9d73116a133 --- /dev/null +++ b/FirebaseVertexAI/Tests/TestApp/Resources/placeholder.txt @@ -0,0 +1 @@ +// Placeholder file to create folder. diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj/project.pbxproj b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj/project.pbxproj index f10063c8646..ede5320985b 100644 --- a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj/project.pbxproj +++ b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj/project.pbxproj @@ -12,11 +12,11 @@ 866138602CC943DE00F4B78E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8661385F2CC943DE00F4B78E /* Assets.xcassets */; }; 866138642CC943DE00F4B78E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 866138632CC943DE00F4B78E /* Preview Assets.xcassets */; }; 8661386E2CC943DE00F4B78E /* IntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8661386D2CC943DE00F4B78E /* IntegrationTests.swift */; }; + 868A7C482CCA931B00E449DD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 868A7C462CCA931B00E449DD /* GoogleService-Info.plist */; }; 8692F2982CC9477800539E8F /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 8692F2972CC9477800539E8F /* FirebaseAppCheck */; }; 8692F29A2CC9477800539E8F /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 8692F2992CC9477800539E8F /* FirebaseAuth */; }; 8692F29C2CC9477800539E8F /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 8692F29B2CC9477800539E8F /* FirebaseStorage */; }; 8692F29E2CC9477800539E8F /* FirebaseVertexAI in Frameworks */ = {isa = PBXBuildFile; productRef = 8692F29D2CC9477800539E8F /* FirebaseVertexAI */; }; - 8692F2A02CC948C100539E8F /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8692F29F2CC948C100539E8F /* GoogleService-Info.plist */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -38,7 +38,7 @@ 866138632CC943DE00F4B78E /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 866138692CC943DE00F4B78E /* IntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 8661386D2CC943DE00F4B78E /* IntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegrationTests.swift; sourceTree = ""; }; - 8692F29F2CC948C100539E8F /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 868A7C462CCA931B00E449DD /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -67,6 +67,7 @@ isa = PBXGroup; children = ( 8661385A2CC943DD00F4B78E /* VertexAITestApp */, + 868A7C472CCA931B00E449DD /* Resources */, 8661386C2CC943DE00F4B78E /* IntegrationTests */, 866138592CC943DD00F4B78E /* Products */, ); @@ -88,7 +89,6 @@ 8661385D2CC943DD00F4B78E /* ContentView.swift */, 8661385F2CC943DE00F4B78E /* Assets.xcassets */, 866138612CC943DE00F4B78E /* VertexAITestApp.entitlements */, - 8692F29F2CC948C100539E8F /* GoogleService-Info.plist */, 866138622CC943DE00F4B78E /* Preview Content */, ); path = VertexAITestApp; @@ -110,6 +110,14 @@ path = IntegrationTests; sourceTree = ""; }; + 868A7C472CCA931B00E449DD /* Resources */ = { + isa = PBXGroup; + children = ( + 868A7C462CCA931B00E449DD /* GoogleService-Info.plist */, + ); + path = Resources; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -202,7 +210,7 @@ files = ( 866138642CC943DE00F4B78E /* Preview Assets.xcassets in Resources */, 866138602CC943DE00F4B78E /* Assets.xcassets in Resources */, - 8692F2A02CC948C100539E8F /* GoogleService-Info.plist in Resources */, + 868A7C482CCA931B00E449DD /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/scripts/build.sh b/scripts/build.sh index f3f5525a29b..261a88eda56 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -503,6 +503,15 @@ case "$product-$platform-$method" in build ;; + VertexIntegration-*-*) + RunXcodebuild \ + -project 'FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj' \ + -scheme "VertexAISample" \ + "${xcb_flags[@]}" \ + build \ + test + ;; + VertexSample-*-*) RunXcodebuild \ -project 'FirebaseVertexAI/Sample/VertexAISample.xcodeproj' \ From 7a0c4ad012b9dddab825fb6b6c33506b4ec3d192 Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Thu, 24 Oct 2024 11:09:21 -0400 Subject: [PATCH 03/14] Fix scheme name --- scripts/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.sh b/scripts/build.sh index 261a88eda56..2ad1e56582f 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -506,7 +506,7 @@ case "$product-$platform-$method" in VertexIntegration-*-*) RunXcodebuild \ -project 'FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj' \ - -scheme "VertexAISample" \ + -scheme "VertexAITestApp" \ "${xcb_flags[@]}" \ build \ test From 65c31c409d4df40bf7f124747dd730256a5903b9 Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Thu, 24 Oct 2024 11:25:37 -0400 Subject: [PATCH 04/14] Add intentionally failing test to verify tests aren't being skipped --- .../Tests/TestApp/IntegrationTests/IntegrationTests.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift b/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift index da6969d9a8f..9177ef6dff1 100644 --- a/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift +++ b/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift @@ -57,6 +57,10 @@ final class IntegrationTests: XCTestCase { ) } + func testShouldFail() { + XCTFail("This should fail if the tests are being run.") + } + // MARK: - Generate Content func testGenerateContent() async throws { From c50ccdab1b77fd6e622949baca21c1f3c2da47ef Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Thu, 24 Oct 2024 13:59:38 -0400 Subject: [PATCH 05/14] Add AppCheckDebugProvider --- .../Tests/TestApp/VertexAITestApp/VertexAITestApp.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.swift b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.swift index 43254830957..a54152a455f 100644 --- a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.swift +++ b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.swift @@ -12,12 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +import FirebaseAppCheck import FirebaseCore import SwiftUI @main struct VertexAITestApp: App { init() { + AppCheck.setAppCheckProviderFactory(AppCheckDebugProviderFactory()) FirebaseApp.configure() } From 501100919a65ef4d7e97980572cb0d617d47faa4 Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Thu, 24 Oct 2024 14:00:10 -0400 Subject: [PATCH 06/14] Add FirebaseAuth --- .../IntegrationTests/IntegrationTests.swift | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift b/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift index 9177ef6dff1..ce3d2586093 100644 --- a/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift +++ b/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +import FirebaseAuth import FirebaseCore import FirebaseVertexAI import XCTest @@ -40,12 +41,27 @@ final class IntegrationTests: XCTestCase { var vertex: VertexAI! var model: GenerativeModel! + static let emailEnvVar = "VERTEXAI_INTEGRATION_AUTH_EMAIL_1" + static let passwordEnvVar = "VERTEXAI_INTEGRATION_AUTH_EMAIL_1_PW" + override func setUp() async throws { - try XCTSkipIf(ProcessInfo.processInfo.environment["VertexAIRunIntegrationTests"] == nil, """ + let environment = ProcessInfo.processInfo.environment + try XCTSkipIf(environment["VertexAIRunIntegrationTests"] == nil, """ Vertex AI integration tests skipped; to enable them, set the VertexAIRunIntegrationTests \ environment variable in Xcode or CI jobs. """) + let email = try XCTUnwrap( + environment[IntegrationTests.emailEnvVar], + "No email address specified in environment variable \(IntegrationTests.emailEnvVar)." + ) + let password = try XCTUnwrap( + environment[IntegrationTests.passwordEnvVar], + "No email address specified in environment variable \(IntegrationTests.passwordEnvVar)." + ) + + try await Auth.auth().signIn(withEmail: email, password: password) + vertex = VertexAI.vertexAI() model = vertex.generativeModel( modelName: "gemini-1.5-flash", @@ -57,10 +73,6 @@ final class IntegrationTests: XCTestCase { ) } - func testShouldFail() { - XCTFail("This should fail if the tests are being run.") - } - // MARK: - Generate Content func testGenerateContent() async throws { @@ -122,6 +134,18 @@ final class IntegrationTests: XCTestCase { XCTAssertEqual(response.totalBillableCharacters, 35) } + func testCountTokens_userAuth_fileData() async throws { + let fileData = FileDataPart( + uri: "gs://ios-opensource-samples.appspot.com/vertexai/authenticated/user/6FwXhmYnM8VBr655PrQQiWfxqiS2/red.webp", + mimeType: "image/jpeg" + ) + + let response = try await model.countTokens(fileData) + + XCTAssertEqual(response.totalTokens, 266) + XCTAssertEqual(response.totalBillableCharacters, 35) + } + func testCountTokens_functionCalling() async throws { let sumDeclaration = FunctionDeclaration( name: "sum", From 164adac7d3977f81eaf5a5357790bd30ef2a5f03 Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Thu, 24 Oct 2024 15:31:43 -0400 Subject: [PATCH 07/14] Add env vars to the job --- .github/workflows/vertexai.yml | 3 +++ .../Tests/TestApp/IntegrationTests/IntegrationTests.swift | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/vertexai.yml b/.github/workflows/vertexai.yml index eaafc9195a5..cad1b685c6d 100644 --- a/.github/workflows/vertexai.yml +++ b/.github/workflows/vertexai.yml @@ -137,6 +137,9 @@ jobs: needs: spm-package-resolved env: TEST_RUNNER_VertexAIRunIntegrationTests: 1 + TEST_RUNNER_VertexAIIntegrationAuthEmail1: ${{ secrets.VERTEXAI_INTEGRATION_AUTH_EMAIL_1 }} + TEST_RUNNER_VertexAIIntegrationAuthEmailPassword1: ${{ secrets.VERTEXAI_INTEGRATION_AUTH_EMAIL_1_PW }} + TEST_RUNNER_FIRAAppCheckDebugToken: ${{ secrets.VERTEXAI_INTEGRATION_FAC_DEBUG_TOKEN }} FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1 plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} steps: diff --git a/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift b/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift index ce3d2586093..2a0eb2d8d38 100644 --- a/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift +++ b/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift @@ -41,8 +41,8 @@ final class IntegrationTests: XCTestCase { var vertex: VertexAI! var model: GenerativeModel! - static let emailEnvVar = "VERTEXAI_INTEGRATION_AUTH_EMAIL_1" - static let passwordEnvVar = "VERTEXAI_INTEGRATION_AUTH_EMAIL_1_PW" + static let emailEnvVar = "VertexAIIntegrationAuthEmail1" + static let passwordEnvVar = "VertexAIIntegrationAuthEmailPassword1" override func setUp() async throws { let environment = ProcessInfo.processInfo.environment From d2ed570521fbdd568d5df49187540b83d0fc3a62 Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Thu, 24 Oct 2024 17:54:43 -0400 Subject: [PATCH 08/14] Update plist, add Storage, check invalid user fails --- .github/workflows/vertexai.yml | 4 +- .../IntegrationTests/IntegrationTests.swift | 57 ++++++++++++++---- .../gha-encrypted/vertexai-testapp.plist.gpg | Bin 0 -> 621 bytes 3 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 scripts/gha-encrypted/vertexai-testapp.plist.gpg diff --git a/.github/workflows/vertexai.yml b/.github/workflows/vertexai.yml index cad1b685c6d..ee9f9f6ba1a 100644 --- a/.github/workflows/vertexai.yml +++ b/.github/workflows/vertexai.yml @@ -125,7 +125,7 @@ jobs: retry_wait_seconds: 120 command: scripts/build.sh FirebaseVertexAIIntegration ${{ matrix.target }} spm - spm-testapp-integration: + testapp-integration: strategy: matrix: target: [iOS] @@ -149,7 +149,7 @@ jobs: path: .build key: ${{needs.spm-package-resolved.outputs.cache_key}} - name: Install Secret GoogleService-Info.plist - run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/vertexai-integration.plist.gpg \ + run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/vertexai-testapp.plist.gpg \ FirebaseVertexAI/Tests/TestApp/Resources/GoogleService-Info.plist "$plist_secret" - name: Xcode run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer diff --git a/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift b/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift index 2a0eb2d8d38..121b6555d6a 100644 --- a/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift +++ b/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift @@ -14,6 +14,7 @@ import FirebaseAuth import FirebaseCore +import FirebaseStorage import FirebaseVertexAI import XCTest @@ -40,6 +41,8 @@ final class IntegrationTests: XCTestCase { var vertex: VertexAI! var model: GenerativeModel! + var storage: Storage! + var userID = "" static let emailEnvVar = "VertexAIIntegrationAuthEmail1" static let passwordEnvVar = "VertexAIIntegrationAuthEmailPassword1" @@ -60,7 +63,8 @@ final class IntegrationTests: XCTestCase { "No email address specified in environment variable \(IntegrationTests.passwordEnvVar)." ) - try await Auth.auth().signIn(withEmail: email, password: password) + let authResult = try await Auth.auth().signIn(withEmail: email, password: password) + userID = authResult.user.uid vertex = VertexAI.vertexAI() model = vertex.generativeModel( @@ -71,6 +75,8 @@ final class IntegrationTests: XCTestCase { toolConfig: .init(functionCallingConfig: .none()), systemInstruction: systemInstruction ) + + storage = Storage.storage() } // MARK: - Generate Content @@ -122,11 +128,9 @@ final class IntegrationTests: XCTestCase { } #endif // canImport(UIKit) - func testCountTokens_image_fileData() async throws { - let fileData = FileDataPart( - uri: "gs://ios-opensource-samples.appspot.com/ios/public/blank.jpg", - mimeType: "image/jpeg" - ) + func testCountTokens_image_fileData_public() async throws { + let storageRef = storage.reference(withPath: "vertexai/public/green.png") + let fileData = FileDataPart(uri: storageRef.gsURI, mimeType: "image/png") let response = try await model.countTokens(fileData) @@ -134,11 +138,9 @@ final class IntegrationTests: XCTestCase { XCTAssertEqual(response.totalBillableCharacters, 35) } - func testCountTokens_userAuth_fileData() async throws { - let fileData = FileDataPart( - uri: "gs://ios-opensource-samples.appspot.com/vertexai/authenticated/user/6FwXhmYnM8VBr655PrQQiWfxqiS2/red.webp", - mimeType: "image/jpeg" - ) + func testCountTokens_image_fileData_requiresAuth_signedIn() async throws { + let storageRef = storage.reference(withPath: "vertexai/authenticated/all_users/yellow.jpg") + let fileData = FileDataPart(uri: storageRef.gsURI, mimeType: "image/jpeg") let response = try await model.countTokens(fileData) @@ -146,6 +148,33 @@ final class IntegrationTests: XCTestCase { XCTAssertEqual(response.totalBillableCharacters, 35) } + func testCountTokens_image_fileData_requiresUserAuth_userSignedIn() async throws { + let storageRef = storage.reference(withPath: "vertexai/authenticated/user/\(userID)/red.webp") + + let fileData = FileDataPart(uri: storageRef.gsURI, mimeType: "image/webp") + + let response = try await model.countTokens(fileData) + + XCTAssertEqual(response.totalTokens, 266) + XCTAssertEqual(response.totalBillableCharacters, 35) + } + + func testCountTokens_image_fileData_requiresUserAuth_wrongUser_permissionDenied() async throws { + let userID = "3MjEzU6JIobWvHdCYHicnDMcPpQ2" + let storageRef = storage.reference(withPath: "vertexai/authenticated/user/\(userID)/pink.webp") + + let fileData = FileDataPart(uri: storageRef.gsURI, mimeType: "image/webp") + + do { + _ = try await model.countTokens(fileData) + XCTFail("Expected to throw an error.") + } catch { + let errorDescription = String(describing: error) + XCTAssertTrue(errorDescription.contains("403")) + XCTAssertTrue(errorDescription.contains("The caller does not have permission")) + } + } + func testCountTokens_functionCalling() async throws { let sumDeclaration = FunctionDeclaration( name: "sum", @@ -192,3 +221,9 @@ final class IntegrationTests: XCTestCase { XCTAssertEqual(response.totalBillableCharacters, 59) } } + +extension StorageReference { + var gsURI: String { + return "gs://\(bucket)/\(fullPath)" + } +} diff --git a/scripts/gha-encrypted/vertexai-testapp.plist.gpg b/scripts/gha-encrypted/vertexai-testapp.plist.gpg new file mode 100644 index 0000000000000000000000000000000000000000..47f836feff32d4e1d51285ca1bfc137928a1b903 GIT binary patch literal 621 zcmV-z0+RiV4Fm}T2ww7uPXf}QYx>gZ0cA3#5bfl=yNRrOXnS3ha>3)E!1Y| z)}B-o=h)uDn#$6!;=NWPngr+y9{y4k(1HaWT7#0$;y|kN4bNEWnL8xKU!T-JyYpl`PeFrVrKQrUb(b}Y_1t$|W^20oVz+aVB zBTyU9wX^JK&CVa+;;yo@O}`H7 zz@Pw%3+MJ^IL1F|@zH)qH$qJu8`w)vXR!@d>>5E>)C8%qFYJ|dIBpvqz?Q6$ He0efuWP~n4 literal 0 HcmV?d00001 From faccf504fb3671cf5813310e08f82c1bb7c5aae9 Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Fri, 25 Oct 2024 16:04:23 -0400 Subject: [PATCH 09/14] Restructure TestApp for future CocoaPods support. --- .github/workflows/vertexai.yml | 14 +-- .../AccentColor.colorset/Contents.json | 0 .../AppIcon.appiconset/Contents.json | 0 .../Assets.xcassets/Contents.json | 0 .../Preview Assets.xcassets/Contents.json | 0 .../TestApp.entitlements} | 0 .../Tests/TestApp/Resources/placeholder.txt | 1 - .../ContentView.swift | 0 .../TestApp.swift} | 2 +- .../Integration}/IntegrationTests.swift | 27 +---- .../VertexAITestApp.xcodeproj/project.pbxproj | 110 ++++++++++-------- .../VertexAI/TestApp-Credentials.swift.gpg | Bin 0 -> 602 bytes .../TestApp-GoogleService-Info.plist.gpg} | Bin 13 files changed, 74 insertions(+), 80 deletions(-) rename FirebaseVertexAI/Tests/TestApp/{VertexAITestApp => Resources}/Assets.xcassets/AccentColor.colorset/Contents.json (100%) rename FirebaseVertexAI/Tests/TestApp/{VertexAITestApp => Resources}/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename FirebaseVertexAI/Tests/TestApp/{VertexAITestApp => Resources}/Assets.xcassets/Contents.json (100%) rename FirebaseVertexAI/Tests/TestApp/{VertexAITestApp => Resources}/Preview Content/Preview Assets.xcassets/Contents.json (100%) rename FirebaseVertexAI/Tests/TestApp/{VertexAITestApp/VertexAITestApp.entitlements => Resources/TestApp.entitlements} (100%) delete mode 100644 FirebaseVertexAI/Tests/TestApp/Resources/placeholder.txt rename FirebaseVertexAI/Tests/TestApp/{VertexAITestApp => Sources}/ContentView.swift (100%) rename FirebaseVertexAI/Tests/TestApp/{VertexAITestApp/VertexAITestApp.swift => Sources/TestApp.swift} (96%) rename FirebaseVertexAI/Tests/TestApp/{IntegrationTests => Tests/Integration}/IntegrationTests.swift (88%) create mode 100644 scripts/gha-encrypted/VertexAI/TestApp-Credentials.swift.gpg rename scripts/gha-encrypted/{vertexai-testapp.plist.gpg => VertexAI/TestApp-GoogleService-Info.plist.gpg} (100%) diff --git a/.github/workflows/vertexai.yml b/.github/workflows/vertexai.yml index ee9f9f6ba1a..9cc70054bbb 100644 --- a/.github/workflows/vertexai.yml +++ b/.github/workflows/vertexai.yml @@ -136,12 +136,9 @@ jobs: runs-on: ${{ matrix.os }} needs: spm-package-resolved env: - TEST_RUNNER_VertexAIRunIntegrationTests: 1 - TEST_RUNNER_VertexAIIntegrationAuthEmail1: ${{ secrets.VERTEXAI_INTEGRATION_AUTH_EMAIL_1 }} - TEST_RUNNER_VertexAIIntegrationAuthEmailPassword1: ${{ secrets.VERTEXAI_INTEGRATION_AUTH_EMAIL_1_PW }} TEST_RUNNER_FIRAAppCheckDebugToken: ${{ secrets.VERTEXAI_INTEGRATION_FAC_DEBUG_TOKEN }} FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1 - plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }} + secrets_passphrase: ${{ secrets.GHASecretsGPGPassphrase1 }} steps: - uses: actions/checkout@v4 - uses: actions/cache/restore@v4 @@ -149,12 +146,13 @@ jobs: path: .build key: ${{needs.spm-package-resolved.outputs.cache_key}} - name: Install Secret GoogleService-Info.plist - run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/vertexai-testapp.plist.gpg \ - FirebaseVertexAI/Tests/TestApp/Resources/GoogleService-Info.plist "$plist_secret" + run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/VertexAI/TestApp-GoogleService-Info.plist.gpg \ + FirebaseVertexAI/Tests/TestApp/Resources/GoogleService-Info.plist "$secrets_passphrase" + - name: Install Secret Credentials.swift + run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/VertexAI/TestApp-Credentials.swift.gpg \ + FirebaseVertexAI/Tests/TestApp/Tests/Integration/Credentials.swift "$secrets_passphrase" - name: Xcode run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app/Contents/Developer - - name: Initialize xcodebuild - run: scripts/setup_spm_tests.sh - name: Run IntegrationTests run: scripts/build.sh VertexIntegration ${{ matrix.target }} diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/AccentColor.colorset/Contents.json b/FirebaseVertexAI/Tests/TestApp/Resources/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/AccentColor.colorset/Contents.json rename to FirebaseVertexAI/Tests/TestApp/Resources/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/FirebaseVertexAI/Tests/TestApp/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/AppIcon.appiconset/Contents.json rename to FirebaseVertexAI/Tests/TestApp/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/Contents.json b/FirebaseVertexAI/Tests/TestApp/Resources/Assets.xcassets/Contents.json similarity index 100% rename from FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Assets.xcassets/Contents.json rename to FirebaseVertexAI/Tests/TestApp/Resources/Assets.xcassets/Contents.json diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Preview Content/Preview Assets.xcassets/Contents.json b/FirebaseVertexAI/Tests/TestApp/Resources/Preview Content/Preview Assets.xcassets/Contents.json similarity index 100% rename from FirebaseVertexAI/Tests/TestApp/VertexAITestApp/Preview Content/Preview Assets.xcassets/Contents.json rename to FirebaseVertexAI/Tests/TestApp/Resources/Preview Content/Preview Assets.xcassets/Contents.json diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.entitlements b/FirebaseVertexAI/Tests/TestApp/Resources/TestApp.entitlements similarity index 100% rename from FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.entitlements rename to FirebaseVertexAI/Tests/TestApp/Resources/TestApp.entitlements diff --git a/FirebaseVertexAI/Tests/TestApp/Resources/placeholder.txt b/FirebaseVertexAI/Tests/TestApp/Resources/placeholder.txt deleted file mode 100644 index 9d73116a133..00000000000 --- a/FirebaseVertexAI/Tests/TestApp/Resources/placeholder.txt +++ /dev/null @@ -1 +0,0 @@ -// Placeholder file to create folder. diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/ContentView.swift b/FirebaseVertexAI/Tests/TestApp/Sources/ContentView.swift similarity index 100% rename from FirebaseVertexAI/Tests/TestApp/VertexAITestApp/ContentView.swift rename to FirebaseVertexAI/Tests/TestApp/Sources/ContentView.swift diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.swift b/FirebaseVertexAI/Tests/TestApp/Sources/TestApp.swift similarity index 96% rename from FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.swift rename to FirebaseVertexAI/Tests/TestApp/Sources/TestApp.swift index a54152a455f..2226e352203 100644 --- a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp/VertexAITestApp.swift +++ b/FirebaseVertexAI/Tests/TestApp/Sources/TestApp.swift @@ -17,7 +17,7 @@ import FirebaseCore import SwiftUI @main -struct VertexAITestApp: App { +struct TestApp: App { init() { AppCheck.setAppCheckProviderFactory(AppCheckDebugProviderFactory()) FirebaseApp.configure() diff --git a/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift b/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift similarity index 88% rename from FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift rename to FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift index 121b6555d6a..b90a13515a6 100644 --- a/FirebaseVertexAI/Tests/TestApp/IntegrationTests/IntegrationTests.swift +++ b/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift @@ -42,29 +42,14 @@ final class IntegrationTests: XCTestCase { var vertex: VertexAI! var model: GenerativeModel! var storage: Storage! - var userID = "" - - static let emailEnvVar = "VertexAIIntegrationAuthEmail1" - static let passwordEnvVar = "VertexAIIntegrationAuthEmailPassword1" + var userID1 = "" override func setUp() async throws { - let environment = ProcessInfo.processInfo.environment - try XCTSkipIf(environment["VertexAIRunIntegrationTests"] == nil, """ - Vertex AI integration tests skipped; to enable them, set the VertexAIRunIntegrationTests \ - environment variable in Xcode or CI jobs. - """) - - let email = try XCTUnwrap( - environment[IntegrationTests.emailEnvVar], - "No email address specified in environment variable \(IntegrationTests.emailEnvVar)." - ) - let password = try XCTUnwrap( - environment[IntegrationTests.passwordEnvVar], - "No email address specified in environment variable \(IntegrationTests.passwordEnvVar)." + let authResult = try await Auth.auth().signIn( + withEmail: Credentials.emailAddress1, + password: Credentials.emailPassword1 ) - - let authResult = try await Auth.auth().signIn(withEmail: email, password: password) - userID = authResult.user.uid + userID1 = authResult.user.uid vertex = VertexAI.vertexAI() model = vertex.generativeModel( @@ -149,7 +134,7 @@ final class IntegrationTests: XCTestCase { } func testCountTokens_image_fileData_requiresUserAuth_userSignedIn() async throws { - let storageRef = storage.reference(withPath: "vertexai/authenticated/user/\(userID)/red.webp") + let storageRef = storage.reference(withPath: "vertexai/authenticated/user/\(userID1)/red.webp") let fileData = FileDataPart(uri: storageRef.gsURI, mimeType: "image/webp") diff --git a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj/project.pbxproj b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj/project.pbxproj index ede5320985b..145a13b2f90 100644 --- a/FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj/project.pbxproj +++ b/FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj/project.pbxproj @@ -7,12 +7,13 @@ objects = { /* Begin PBXBuildFile section */ - 8661385C2CC943DD00F4B78E /* VertexAITestApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8661385B2CC943DD00F4B78E /* VertexAITestApp.swift */; }; + 8661385C2CC943DD00F4B78E /* TestApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8661385B2CC943DD00F4B78E /* TestApp.swift */; }; 8661385E2CC943DD00F4B78E /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8661385D2CC943DD00F4B78E /* ContentView.swift */; }; - 866138602CC943DE00F4B78E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8661385F2CC943DE00F4B78E /* Assets.xcassets */; }; - 866138642CC943DE00F4B78E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 866138632CC943DE00F4B78E /* Preview Assets.xcassets */; }; 8661386E2CC943DE00F4B78E /* IntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8661386D2CC943DE00F4B78E /* IntegrationTests.swift */; }; 868A7C482CCA931B00E449DD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 868A7C462CCA931B00E449DD /* GoogleService-Info.plist */; }; + 868A7C4F2CCC229F00E449DD /* Credentials.swift in Sources */ = {isa = PBXBuildFile; fileRef = 868A7C4D2CCC1F4700E449DD /* Credentials.swift */; }; + 868A7C522CCC263300E449DD /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 868A7C502CCC263300E449DD /* Preview Assets.xcassets */; }; + 868A7C542CCC26B500E449DD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 868A7C532CCC26B500E449DD /* Assets.xcassets */; }; 8692F2982CC9477800539E8F /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = 8692F2972CC9477800539E8F /* FirebaseAppCheck */; }; 8692F29A2CC9477800539E8F /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 8692F2992CC9477800539E8F /* FirebaseAuth */; }; 8692F29C2CC9477800539E8F /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 8692F29B2CC9477800539E8F /* FirebaseStorage */; }; @@ -30,15 +31,16 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 866138582CC943DD00F4B78E /* VertexAITestApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VertexAITestApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 8661385B2CC943DD00F4B78E /* VertexAITestApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VertexAITestApp.swift; sourceTree = ""; }; + 866138582CC943DD00F4B78E /* VertexAITestApp-SPM.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "VertexAITestApp-SPM.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 8661385B2CC943DD00F4B78E /* TestApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestApp.swift; sourceTree = ""; }; 8661385D2CC943DD00F4B78E /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; - 8661385F2CC943DE00F4B78E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 866138612CC943DE00F4B78E /* VertexAITestApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = VertexAITestApp.entitlements; sourceTree = ""; }; - 866138632CC943DE00F4B78E /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 866138692CC943DE00F4B78E /* IntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 866138692CC943DE00F4B78E /* IntegrationTests-SPM.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "IntegrationTests-SPM.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 8661386D2CC943DE00F4B78E /* IntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegrationTests.swift; sourceTree = ""; }; 868A7C462CCA931B00E449DD /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 868A7C4D2CCC1F4700E449DD /* Credentials.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Credentials.swift; sourceTree = ""; }; + 868A7C502CCC263300E449DD /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 868A7C532CCC26B500E449DD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 868A7C552CCC271300E449DD /* TestApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TestApp.entitlements; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -66,9 +68,9 @@ 8661384F2CC943DD00F4B78E = { isa = PBXGroup; children = ( - 8661385A2CC943DD00F4B78E /* VertexAITestApp */, + 868A7C562CCC277100E449DD /* Sources */, + 868A7C582CCC27AF00E449DD /* Tests */, 868A7C472CCA931B00E449DD /* Resources */, - 8661386C2CC943DE00F4B78E /* IntegrationTests */, 866138592CC943DD00F4B78E /* Products */, ); sourceTree = ""; @@ -76,54 +78,63 @@ 866138592CC943DD00F4B78E /* Products */ = { isa = PBXGroup; children = ( - 866138582CC943DD00F4B78E /* VertexAITestApp.app */, - 866138692CC943DE00F4B78E /* IntegrationTests.xctest */, + 866138582CC943DD00F4B78E /* VertexAITestApp-SPM.app */, + 866138692CC943DE00F4B78E /* IntegrationTests-SPM.xctest */, ); name = Products; sourceTree = ""; }; - 8661385A2CC943DD00F4B78E /* VertexAITestApp */ = { + 868A7C472CCA931B00E449DD /* Resources */ = { isa = PBXGroup; children = ( - 8661385B2CC943DD00F4B78E /* VertexAITestApp.swift */, - 8661385D2CC943DD00F4B78E /* ContentView.swift */, - 8661385F2CC943DE00F4B78E /* Assets.xcassets */, - 866138612CC943DE00F4B78E /* VertexAITestApp.entitlements */, - 866138622CC943DE00F4B78E /* Preview Content */, + 868A7C512CCC263300E449DD /* Preview Content */, + 868A7C532CCC26B500E449DD /* Assets.xcassets */, + 868A7C552CCC271300E449DD /* TestApp.entitlements */, + 868A7C462CCA931B00E449DD /* GoogleService-Info.plist */, ); - path = VertexAITestApp; + path = Resources; sourceTree = ""; }; - 866138622CC943DE00F4B78E /* Preview Content */ = { + 868A7C512CCC263300E449DD /* Preview Content */ = { isa = PBXGroup; children = ( - 866138632CC943DE00F4B78E /* Preview Assets.xcassets */, + 868A7C502CCC263300E449DD /* Preview Assets.xcassets */, ); path = "Preview Content"; sourceTree = ""; }; - 8661386C2CC943DE00F4B78E /* IntegrationTests */ = { + 868A7C562CCC277100E449DD /* Sources */ = { isa = PBXGroup; children = ( + 8661385B2CC943DD00F4B78E /* TestApp.swift */, + 8661385D2CC943DD00F4B78E /* ContentView.swift */, + ); + path = Sources; + sourceTree = ""; + }; + 868A7C572CCC27AF00E449DD /* Integration */ = { + isa = PBXGroup; + children = ( + 868A7C4D2CCC1F4700E449DD /* Credentials.swift */, 8661386D2CC943DE00F4B78E /* IntegrationTests.swift */, ); - path = IntegrationTests; + path = Integration; sourceTree = ""; }; - 868A7C472CCA931B00E449DD /* Resources */ = { + 868A7C582CCC27AF00E449DD /* Tests */ = { isa = PBXGroup; children = ( - 868A7C462CCA931B00E449DD /* GoogleService-Info.plist */, + 868A7C572CCC27AF00E449DD /* Integration */, ); - path = Resources; + path = Tests; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 866138572CC943DD00F4B78E /* VertexAITestApp */ = { + 866138572CC943DD00F4B78E /* VertexAITestApp-SPM */ = { isa = PBXNativeTarget; - buildConfigurationList = 8661387D2CC943DE00F4B78E /* Build configuration list for PBXNativeTarget "VertexAITestApp" */; + buildConfigurationList = 8661387D2CC943DE00F4B78E /* Build configuration list for PBXNativeTarget "VertexAITestApp-SPM" */; buildPhases = ( 866138542CC943DD00F4B78E /* Sources */, 866138552CC943DD00F4B78E /* Frameworks */, @@ -133,7 +144,7 @@ ); dependencies = ( ); - name = VertexAITestApp; + name = "VertexAITestApp-SPM"; packageProductDependencies = ( 8692F2972CC9477800539E8F /* FirebaseAppCheck */, 8692F2992CC9477800539E8F /* FirebaseAuth */, @@ -141,12 +152,12 @@ 8692F29D2CC9477800539E8F /* FirebaseVertexAI */, ); productName = VertexAITestApp; - productReference = 866138582CC943DD00F4B78E /* VertexAITestApp.app */; + productReference = 866138582CC943DD00F4B78E /* VertexAITestApp-SPM.app */; productType = "com.apple.product-type.application"; }; - 866138682CC943DE00F4B78E /* IntegrationTests */ = { + 866138682CC943DE00F4B78E /* IntegrationTests-SPM */ = { isa = PBXNativeTarget; - buildConfigurationList = 866138802CC943DE00F4B78E /* Build configuration list for PBXNativeTarget "IntegrationTests" */; + buildConfigurationList = 866138802CC943DE00F4B78E /* Build configuration list for PBXNativeTarget "IntegrationTests-SPM" */; buildPhases = ( 866138652CC943DE00F4B78E /* Sources */, 866138662CC943DE00F4B78E /* Frameworks */, @@ -157,9 +168,9 @@ dependencies = ( 8661386B2CC943DE00F4B78E /* PBXTargetDependency */, ); - name = IntegrationTests; + name = "IntegrationTests-SPM"; productName = VertexAITestAppTests; - productReference = 866138692CC943DE00F4B78E /* IntegrationTests.xctest */; + productReference = 866138692CC943DE00F4B78E /* IntegrationTests-SPM.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ @@ -197,8 +208,8 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 866138572CC943DD00F4B78E /* VertexAITestApp */, - 866138682CC943DE00F4B78E /* IntegrationTests */, + 866138572CC943DD00F4B78E /* VertexAITestApp-SPM */, + 866138682CC943DE00F4B78E /* IntegrationTests-SPM */, ); }; /* End PBXProject section */ @@ -208,8 +219,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 866138642CC943DE00F4B78E /* Preview Assets.xcassets in Resources */, - 866138602CC943DE00F4B78E /* Assets.xcassets in Resources */, + 868A7C522CCC263300E449DD /* Preview Assets.xcassets in Resources */, + 868A7C542CCC26B500E449DD /* Assets.xcassets in Resources */, 868A7C482CCA931B00E449DD /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -229,7 +240,7 @@ buildActionMask = 2147483647; files = ( 8661385E2CC943DD00F4B78E /* ContentView.swift in Sources */, - 8661385C2CC943DD00F4B78E /* VertexAITestApp.swift in Sources */, + 8661385C2CC943DD00F4B78E /* TestApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -237,6 +248,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 868A7C4F2CCC229F00E449DD /* Credentials.swift in Sources */, 8661386E2CC943DE00F4B78E /* IntegrationTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -246,7 +258,7 @@ /* Begin PBXTargetDependency section */ 8661386B2CC943DE00F4B78E /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 866138572CC943DD00F4B78E /* VertexAITestApp */; + target = 866138572CC943DD00F4B78E /* VertexAITestApp-SPM */; targetProxy = 8661386A2CC943DE00F4B78E /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -371,10 +383,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_ENTITLEMENTS = VertexAITestApp/VertexAITestApp.entitlements; + CODE_SIGN_ENTITLEMENTS = Resources/TestApp.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"VertexAITestApp/Preview Content\""; + DEVELOPMENT_ASSET_PATHS = "\"Resources/Preview Content\""; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; @@ -407,10 +419,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_ENTITLEMENTS = VertexAITestApp/VertexAITestApp.entitlements; + CODE_SIGN_ENTITLEMENTS = Resources/TestApp.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"VertexAITestApp/Preview Content\""; + DEVELOPMENT_ASSET_PATHS = "\"Resources/Preview Content\""; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; @@ -456,7 +468,7 @@ SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VertexAITestApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/VertexAITestApp"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VertexAITestApp-SPM.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/VertexAITestApp-SPM"; }; name = Debug; }; @@ -478,7 +490,7 @@ SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VertexAITestApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/VertexAITestApp"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VertexAITestApp-SPM.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/VertexAITestApp-SPM"; }; name = Release; }; @@ -494,7 +506,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 8661387D2CC943DE00F4B78E /* Build configuration list for PBXNativeTarget "VertexAITestApp" */ = { + 8661387D2CC943DE00F4B78E /* Build configuration list for PBXNativeTarget "VertexAITestApp-SPM" */ = { isa = XCConfigurationList; buildConfigurations = ( 8661387E2CC943DE00F4B78E /* Debug */, @@ -503,7 +515,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 866138802CC943DE00F4B78E /* Build configuration list for PBXNativeTarget "IntegrationTests" */ = { + 866138802CC943DE00F4B78E /* Build configuration list for PBXNativeTarget "IntegrationTests-SPM" */ = { isa = XCConfigurationList; buildConfigurations = ( 866138812CC943DE00F4B78E /* Debug */, diff --git a/scripts/gha-encrypted/VertexAI/TestApp-Credentials.swift.gpg b/scripts/gha-encrypted/VertexAI/TestApp-Credentials.swift.gpg new file mode 100644 index 0000000000000000000000000000000000000000..f7beaecccb00ad479e8fb33659fe1cd8ec54158b GIT binary patch literal 602 zcmV-g0;TI=Df-gs0mBR|TFzsLJkS@s%|&wf(LU16uVk<&I{?}> zeG#J0)Txsul0PYEk{(|)(cEhc*qN4%3h{}rlE`mFl_JMEaCtKwBRDQGh5APcH$l7X{(be-A{ddV< zU~})*Cm<>>8f|wBg^^kXYt1!bf`$?vW|Bm#Vb*vAKMM>cuo+4BI?K?6B;?o_$xT9+({Cv6z2EnQkk*9^+=mZ>`WQYM{G&%e`*7{ls56K znY4x>dUg8Y+chXpeQ|<(Ywn~rXaWM?7HU9PuA{hlpp{EZMyr?i;Nwu|(am~~Qzy27 zdY<3jz(=?y@dgN#9~=+t%U>{SCQ(mWU1sb0<^{F95DKlwJs05Mx8V@L7X={mRyGwm zZRkEQ+ownGG)z*MCvAj1ND&ILD@*`3B!OpYS3WY=wY@*Y4t!ff&6)qYaL)Z=LYrGI o^H&oom>A@35MQ^#O!4ErKm Date: Fri, 25 Oct 2024 16:06:58 -0400 Subject: [PATCH 10/14] Update build.sh to match new scheme --- scripts/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build.sh b/scripts/build.sh index 2ad1e56582f..0a8cdc857a6 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -506,7 +506,7 @@ case "$product-$platform-$method" in VertexIntegration-*-*) RunXcodebuild \ -project 'FirebaseVertexAI/Tests/TestApp/VertexAITestApp.xcodeproj' \ - -scheme "VertexAITestApp" \ + -scheme "VertexAITestApp-SPM" \ "${xcb_flags[@]}" \ build \ test From cf46d14dd001c827674a825dba36da0259217613 Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Fri, 25 Oct 2024 16:34:36 -0400 Subject: [PATCH 11/14] Check that FIRAAppCheckDebugToken provided and tests are running --- .../Tests/TestApp/Tests/Integration/IntegrationTests.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift b/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift index b90a13515a6..ff78dcae943 100644 --- a/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift +++ b/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift @@ -45,6 +45,13 @@ final class IntegrationTests: XCTestCase { var userID1 = "" override func setUp() async throws { + let environment = ProcessInfo.processInfo.environment + if environment["FIRAAppCheckDebugToken"] == nil { + XCTFail("No App Check debug token provided in FIRAAppCheckDebugToken.") + } else { + XCTFail("App Check debug token provided; failing to check that tests are running.") + } + let authResult = try await Auth.auth().signIn( withEmail: Credentials.emailAddress1, password: Credentials.emailPassword1 From f9360831a02805ac249b0a82c0754db3498ef2fd Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Fri, 25 Oct 2024 16:49:12 -0400 Subject: [PATCH 12/14] Revert "Check that FIRAAppCheckDebugToken provided and tests are running" This reverts commit cf46d14dd001c827674a825dba36da0259217613. --- .../Tests/TestApp/Tests/Integration/IntegrationTests.swift | 7 ------- 1 file changed, 7 deletions(-) diff --git a/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift b/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift index ff78dcae943..b90a13515a6 100644 --- a/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift +++ b/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift @@ -45,13 +45,6 @@ final class IntegrationTests: XCTestCase { var userID1 = "" override func setUp() async throws { - let environment = ProcessInfo.processInfo.environment - if environment["FIRAAppCheckDebugToken"] == nil { - XCTFail("No App Check debug token provided in FIRAAppCheckDebugToken.") - } else { - XCTFail("App Check debug token provided; failing to check that tests are running.") - } - let authResult = try await Auth.auth().signIn( withEmail: Credentials.emailAddress1, password: Credentials.emailPassword1 From 62d5b82e9ba3e947d97893b15743fe1642ecae41 Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Fri, 25 Oct 2024 16:51:21 -0400 Subject: [PATCH 13/14] Re-check FIRAAppCheckDebugToken --- .../TestApp/Tests/Integration/IntegrationTests.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift b/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift index b90a13515a6..bb971f1fbec 100644 --- a/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift +++ b/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift @@ -64,6 +64,18 @@ final class IntegrationTests: XCTestCase { storage = Storage.storage() } + func testDebugTokenProvided() { + if ProcessInfo.processInfo.environment["FIRAAppCheckDebugToken"] == nil { + XCTFail("No App Check debug token provided in FIRAAppCheckDebugToken.") + } + } + + func testDebugTokenNotProvided() { + if ProcessInfo.processInfo.environment["FIRAAppCheckDebugToken"] != nil { + XCTFail("Token not provided; intentionally failing for testing.") + } + } + // MARK: - Generate Content func testGenerateContent() async throws { From 02832ebbf5a3c415adb50f6990cd99bacd81a6aa Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Fri, 25 Oct 2024 17:05:38 -0400 Subject: [PATCH 14/14] Revert "Re-check FIRAAppCheckDebugToken" This reverts commit 62d5b82e9ba3e947d97893b15743fe1642ecae41. --- .../TestApp/Tests/Integration/IntegrationTests.swift | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift b/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift index bb971f1fbec..b90a13515a6 100644 --- a/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift +++ b/FirebaseVertexAI/Tests/TestApp/Tests/Integration/IntegrationTests.swift @@ -64,18 +64,6 @@ final class IntegrationTests: XCTestCase { storage = Storage.storage() } - func testDebugTokenProvided() { - if ProcessInfo.processInfo.environment["FIRAAppCheckDebugToken"] == nil { - XCTFail("No App Check debug token provided in FIRAAppCheckDebugToken.") - } - } - - func testDebugTokenNotProvided() { - if ProcessInfo.processInfo.environment["FIRAAppCheckDebugToken"] != nil { - XCTFail("Token not provided; intentionally failing for testing.") - } - } - // MARK: - Generate Content func testGenerateContent() async throws {