[go: nahoru, domu]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Rollouts] Feature rollouts merge to main #12410

Merged
merged 19 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9c50f5e
[Rollouts] RC interop implementation (#12173)
themiswang Dec 7, 2023
06947d7
[Rollouts]Add a rollout metadata constant (#12209)
ddnan Dec 19, 2023
4a7c1c9
[Rollouts] Crashlytics Rollouts interop Integration (#12200)
themiswang Dec 20, 2023
162f690
[Rollouts] Add integration test app (#12239)
themiswang Jan 5, 2024
40826e8
[Rollouts] Rollouts serialization (#12258)
themiswang Jan 10, 2024
96e2e99
[Rollouts] Implement insert and load logic for rollout metadata in RC…
ddnan Jan 18, 2024
b9b970d
[Rollouts]Writing Rollouts to persistence (#12300)
themiswang Jan 23, 2024
3d9a9a7
[Rollouts] Set active rollout metadata after activating config (#12316)
ddnan Jan 30, 2024
d974256
[Rollouts] Diff rollout metadata for updatedKeys in RemoteConfigUpdat…
ddnan Feb 2, 2024
09d4d56
[Rollouts]Add remote config logic to featureRollouts test app (#12349)
ddnan Feb 6, 2024
5cfc356
[Rollouts] Notify RolloutsState change to Interop subscriber (#12334)
ddnan Feb 12, 2024
6030c01
[Rollouts] Address feature branch comments (#12411)
themiswang Feb 21, 2024
5fa7507
Add Fireperf dependency to feature rollouts test app (#12430)
ddnan Feb 26, 2024
4ffcaef
add release notes and privacy manifest for interop (#12464)
themiswang Mar 4, 2024
c528a52
fix unit test (#12499)
themiswang Mar 8, 2024
5dabfd5
Fix rollouts tests (#12500)
themiswang Mar 8, 2024
37fce03
reword parameter name (#12502)
themiswang Mar 9, 2024
1e3b0e8
edit release notes (#12515)
themiswang Mar 11, 2024
98ecf0e
[Rollouts] Revert constants change in remote config public api test (…
ddnan Mar 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[Rollouts] Rollouts serialization (#12258)
  • Loading branch information
themiswang committed Mar 11, 2024
commit 40826e865d40be063d29e24e59d996457e072f3e
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class CrashlyticsRemoteConfigManager: NSObject {
public static let maxParameterValueLength = 256

var remoteConfig: RemoteConfigInterop
public private(set) var rolloutAssignment: [RolloutAssignment] = []
@objc public private(set) var rolloutAssignment: [RolloutAssignment] = []
weak var persistenceDelegate: CrashlyticsPersistentLog?

@objc public init(remoteConfig: RemoteConfigInterop) {
Expand All @@ -35,6 +35,24 @@ public class CrashlyticsRemoteConfigManager: NSObject {
@objc public func updateRolloutsState(rolloutsState: RolloutsState) {
rolloutAssignment = normalizeRolloutAssignment(assignments: Array(rolloutsState.assignments))
}

@objc public func getRolloutAssignmentsEncodedJson() -> String? {
let contentEncodedRolloutAssignments = rolloutAssignment.map { assignment in
EncodedRolloutAssignment(assignment: assignment)
}

let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
encoder.outputFormatting = .sortedKeys
let encodeData = try? encoder.encode(contentEncodedRolloutAssignments)
if let data = encodeData, let returnString = String(data: data, encoding: .utf8) {
return returnString
}

// TODO(themisw): Hook into core logging functions
themiswang marked this conversation as resolved.
Show resolved Hide resolved
debugPrint("Failed to serialize rollouts", encodeData ?? "nil")
return nil
}
}

private extension CrashlyticsRemoteConfigManager {
Expand Down
34 changes: 34 additions & 0 deletions Crashlytics/Crashlytics/Rollouts/EncodedRolloutAssignment.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 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 FirebaseRemoteConfigInterop
import Foundation

@objc(FIRCLSEncodedRolloutAssignment)
class EncodedRolloutAssignment: NSObject, Codable {
@objc public private(set) var rolloutId: String
@objc public private(set) var variantId: String
@objc public private(set) var templateVersion: Int64
@objc public private(set) var parameterKey: String
@objc public private(set) var parameterValue: String

public init(assignment: RolloutAssignment) {
rolloutId = FileUtility.stringToHexConverter(for: assignment.rolloutId)
variantId = FileUtility.stringToHexConverter(for: assignment.variantId)
templateVersion = assignment.templateVersion
parameterKey = FileUtility.stringToHexConverter(for: assignment.parameterKey)
parameterValue = FileUtility.stringToHexConverter(for: assignment.parameterValue)
super.init()
}
}
38 changes: 38 additions & 0 deletions Crashlytics/Crashlytics/Rollouts/StringToHexConverter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// 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 Foundation

// This is a swift rewrite for the logic in FIRCLSFile for the function FIRCLSFileHexEncodeString()
@objc(FIRCLSwiftFileUtility)
public class FileUtility: NSObject {
@objc public static func stringToHexConverter(for string: String) -> String {
let hexMap = "0123456789abcdef"

var processedString = ""
let utf8Array = string.utf8.map { UInt8($0) }
for c in utf8Array {
let index1 = String.Index(
utf16Offset: Int(c >> 4),
in: hexMap
)
let index2 = String.Index(
utf16Offset: Int(c & 0x0F),
in: hexMap
)
processedString = processedString + String(hexMap[index1]) + String(hexMap[index2])
}
return processedString
}
}
31 changes: 31 additions & 0 deletions Crashlytics/UnitTests/FIRCLSFileTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@

#include "Crashlytics/Crashlytics/Helpers/FIRCLSFile.h"

#if SWIFT_PACKAGE
@import FirebaseCrashlyticsSwift;
#else // Swift Package Manager
#import <FirebaseCrashlytics/FirebaseCrashlytics-Swift.h>
#endif // Cocoapod

#import <XCTest/XCTest.h>

@interface FIRCLSFileTests : XCTestCase
Expand Down Expand Up @@ -169,6 +175,31 @@ - (void)hexEncodingStringWithFile:(FIRCLSFile *)file
buffered ? @"" : @"un");
}

// This is the test to compare FIRCLSwiftFileUtility.stringToHexConverter(for:) and
// FIRCLSFileWriteHexEncodedString return the same hex encoding value
- (void)testHexEncodingStringObjcAndSwiftResultsSame {
NSString *testedValueString = @"是themis的测试数据,输入中文";

FIRCLSFile *unbufferedFile = &_unbufferedFile;
FIRCLSFileWriteHashStart(unbufferedFile);
FIRCLSFileWriteHashEntryHexEncodedString(unbufferedFile, "hex", [testedValueString UTF8String]);
FIRCLSFileWriteHashEnd(unbufferedFile);
NSString *contentsFromObjcHexEncoding = [self contentsOfFileAtPath:self.unbufferedPath];

FIRCLSFile *bufferedFile = &_bufferedFile;
NSString *encodedValue = [FIRCLSwiftFileUtility stringToHexConverterFor:testedValueString];
FIRCLSFileWriteHashStart(bufferedFile);
FIRCLSFileWriteHashKey(bufferedFile, "hex");
FIRCLSFileWriteStringUnquoted(bufferedFile, "\"");
FIRCLSFileWriteStringUnquoted(bufferedFile, [encodedValue UTF8String]);
FIRCLSFileWriteStringUnquoted(bufferedFile, "\"");
FIRCLSFileWriteHashEnd(bufferedFile);
FIRCLSFileFlushWriteBuffer(bufferedFile);
NSString *contentsFromSwiftHexEncoding = [self contentsOfFileAtPath:self.bufferedPath];

XCTAssertTrue([contentsFromObjcHexEncoding isEqualToString:contentsFromSwiftHexEncoding]);
}

#pragma mark -

- (void)testHexEncodingLongString {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ final class CrashlyticsRemoteConfigManagerTests: XCTestCase {
return rollouts
}()

let singleRollout: RolloutsState = {
let assignment1 = RolloutAssignment(
rolloutId: "rollout_1",
variantId: "control",
templateVersion: 1,
parameterKey: "my_feature",
parameterValue: "这是themis的测试数据,输入中文" // check unicode
)
let rollouts = RolloutsState(assignmentList: [assignment1])
return rollouts
}()

let rcInterop = RemoteConfigConfigMock()

func testRemoteConfigManagerProperlyProcessRolloutsState() throws {
Expand All @@ -61,4 +73,15 @@ final class CrashlyticsRemoteConfigManagerTests: XCTestCase {
}
}
}

func testRemoteConfigManagerGenerateEncodedRolloutAssignmentsJson() throws {
let expectedString =
"[{\"parameter_key\":\"6d795f66656174757265\",\"parameter_value\":\"e8bf99e698af7468656d6973e79a84e6b58be8af95e695b0e68daeefbc8ce8be93e585a5e4b8ade69687\",\"rollout_id\":\"726f6c6c6f75745f31\",\"template_version\":1,\"variant_id\":\"636f6e74726f6c\"}]"

let rcManager = CrashlyticsRemoteConfigManager(remoteConfig: rcInterop)
rcManager.updateRolloutsState(rolloutsState: singleRollout)

let string = rcManager.getRolloutAssignmentsEncodedJson()
XCTAssertEqual(string, expectedString)
}
}
7 changes: 4 additions & 3 deletions FirebaseRemoteConfig/Interop/RolloutAssignment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ public class RolloutAssignment: NSObject {
@objc public var parameterKey: String
@objc public var parameterValue: String

public init(rolloutId: String, variantId: String, templateVersion: Int64, parameterKey: String,
parameterValue: String) {
@objc public init(rolloutId: String, variantId: String, templateVersion: Int64,
parameterKey: String,
parameterValue: String) {
self.rolloutId = rolloutId
self.variantId = variantId
self.templateVersion = templateVersion
Expand All @@ -37,7 +38,7 @@ public class RolloutAssignment: NSObject {
public class RolloutsState: NSObject {
@objc public var assignments: Set<RolloutAssignment> = Set()

public init(assignmentList: [RolloutAssignment]) {
@objc public init(assignmentList: [RolloutAssignment]) {
for assignment in assignmentList {
assignments.insert(assignment)
}
Expand Down