]> git.saurik.com Git - apple/security.git/blob - keychain/ckks/tests/CKKSTests+Coalesce.m
Security-58286.60.28.tar.gz
[apple/security.git] / keychain / ckks / tests / CKKSTests+Coalesce.m
1 /*
2 * Copyright (c) 2016 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #if OCTAGON
25
26 #import "keychain/ckks/CKKS.h"
27 #import "keychain/ckks/tests/CKKSTests.h"
28 #import "keychain/ckks/tests/CloudKitMockXCTest.h"
29
30 // Break abstraction.
31 @interface CKKSKeychainView(test)
32 @property NSOperationQueue* operationQueue;
33 @end
34
35 @implementation CloudKitKeychainSyncingTests (CoalesceTests)
36 // These tests check that, if CKKS doesn't start processing an item before a new update comes in,
37 // each case is properly handled.
38
39 - (void)testCoalesceAddModifyItem {
40 [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test.
41
42 NSString* account = @"account-delete-me";
43
44 [self addGenericPassword: @"data" account: account];
45 [self updateGenericPassword: @"otherdata" account:account];
46
47 // We expect a single record to be uploaded.
48 [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
49
50 [self startCKKSSubsystem];
51 OCMVerifyAllWithDelay(self.mockDatabase, 4);
52 }
53
54 - (void)testCoalesceAddModifyModifyItem {
55 [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test.
56
57 NSString* account = @"account-delete-me";
58
59 [self addGenericPassword: @"data" account: account];
60 [self updateGenericPassword: @"otherdata" account:account];
61 [self updateGenericPassword: @"again" account:account];
62
63 // We expect a single record to be uploaded.
64 [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
65
66 [self startCKKSSubsystem];
67 OCMVerifyAllWithDelay(self.mockDatabase, 4);
68 }
69
70 - (void)testCoalesceAddModifyDeleteItem {
71 [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test.
72
73 NSString* account = @"account-delete-me";
74
75 [self addGenericPassword: @"data" account: account];
76 [self updateGenericPassword: @"otherdata" account:account];
77 [self deleteGenericPassword: account];
78
79 // We expect no uploads.
80 [self startCKKSSubsystem];
81 [self.keychainView waitUntilAllOperationsAreFinished];
82 OCMVerifyAllWithDelay(self.mockDatabase, 4);
83 }
84
85 - (void)testCoalesceDeleteAddItem {
86 [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test.
87
88 NSString* account = @"account-delete-me";
89
90 [self addGenericPassword: @"data" account: account];
91
92 // We expect a single record to be uploaded.
93 [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID];
94 [self startCKKSSubsystem];
95 OCMVerifyAllWithDelay(self.mockDatabase, 4);
96 [self waitForCKModifications];
97
98 // Okay, now the delete/add. Note that this is not a coalescing operation, since the new item
99 // will have a completely different UUID, and so will delete the old record and upload the new one.
100
101 [self.keychainView.operationQueue waitUntilAllOperationsAreFinished];
102 self.keychainView.operationQueue.suspended = YES;
103 [self deleteGenericPassword: account];
104 [self addGenericPassword: @"data" account: account];
105
106 [self expectCKModifyRecords:@{SecCKRecordItemType: [NSNumber numberWithUnsignedInteger: 1],
107 SecCKRecordCurrentKeyType: [NSNumber numberWithUnsignedInteger: 1],
108 SecCKRecordDeviceStateType: [NSNumber numberWithUnsignedInteger: 1],
109 }
110 deletedRecordTypeCounts:@{SecCKRecordItemType: [NSNumber numberWithUnsignedInteger: 1]}
111 zoneID:self.keychainZoneID
112 checkModifiedRecord:nil
113 runAfterModification:nil];
114 self.keychainView.operationQueue.suspended = NO;
115 OCMVerifyAllWithDelay(self.mockDatabase, 4);
116 }
117
118 @end
119
120 #endif