PageRenderTime 57ms CodeModel.GetById 16ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 0ms

/core/externals/update-engine/Core/KSUpdateActionTest.m

http://macfuse.googlecode.com/
Objective C | 269 lines | 197 code | 52 blank | 20 comment | 2 complexity | 5bfb7ca4a8475984bacefc40b6508b01 MD5 | raw file
  1// Copyright 2008 Google Inc.
  2//
  3// Licensed under the Apache License, Version 2.0 (the "License");
  4// you may not use this file except in compliance with the License.
  5// You may obtain a copy of the License at
  6//
  7//     http://www.apache.org/licenses/LICENSE-2.0
  8//
  9// Unless required by applicable law or agreed to in writing, software
 10// distributed under the License is distributed on an "AS IS" BASIS,
 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12// See the License for the specific language governing permissions and
 13// limitations under the License.
 14
 15#import <SenTestingKit/SenTestingKit.h>
 16#import "KSUpdateAction.h"
 17#import "KSInstallAction.h"
 18#import "KSActionProcessor.h"
 19#import "KSActionPipe.h"
 20#import "KSCommandRunner.h"
 21#import "NSData+Hash.h"
 22#import "GTMBase64.h"
 23#import <unistd.h>
 24
 25
 26@interface KSUpdateActionTest : SenTestCase {
 27 @private
 28  NSString *successDMGPath_;
 29  NSString *failureDMGPath_;
 30  NSMutableArray *progressArray_;
 31}
 32@end
 33
 34
 35@interface SuccessDelegate : NSObject {
 36  BOOL wasSuccessful_;
 37}
 38
 39- (BOOL)wasSuccessful;
 40
 41@end
 42
 43@implementation SuccessDelegate
 44
 45- (BOOL)wasSuccessful {
 46  return wasSuccessful_;
 47}
 48
 49- (void)processor:(KSActionProcessor *)processor
 50   finishedAction:(KSAction *)action
 51     successfully:(BOOL)wasOK {
 52  wasSuccessful_ = wasOK;
 53}
 54
 55@end
 56
 57
 58@implementation KSUpdateActionTest
 59
 60- (void)setUp {
 61  NSBundle *mainBundle = [NSBundle bundleForClass:[self class]];
 62
 63  successDMGPath_ = [[mainBundle pathForResource:@"Test-SUCCESS"
 64                                          ofType:@"dmg"] retain];
 65
 66  failureDMGPath_ = [[mainBundle pathForResource:@"Test-FAILURE"
 67                                          ofType:@"dmg"] retain];
 68  progressArray_ = [[NSMutableArray array] retain];
 69
 70  STAssertNotNil(successDMGPath_, nil);
 71  STAssertNotNil(failureDMGPath_, nil);
 72  STAssertNotNil(progressArray_, nil);
 73}
 74
 75- (void)tearDown {
 76  [successDMGPath_ release];
 77  [failureDMGPath_ release];
 78  [progressArray_ release];
 79}
 80
 81- (void)testCreation {
 82  KSUpdateAction *action = nil;
 83
 84  // Make sure calling super's designated initializer returns nil
 85  action = [[[KSUpdateAction alloc] initWithActions:nil] autorelease];
 86  STAssertNil(action, nil);
 87
 88  action = [KSUpdateAction actionWithUpdateInfo:nil runner:nil userInitiated:NO];
 89  STAssertNil(action, nil);
 90
 91  KSUpdateInfo *info =
 92    [NSDictionary dictionaryWithObjectsAndKeys:
 93            @"foo", kServerProductID,
 94            [NSURL URLWithString:@"a://a"], kServerCodebaseURL,
 95            [NSNumber numberWithInt:2], kServerCodeSize,
 96            @"zzz", kServerCodeHash,
 97            @"a://b", kServerMoreInfoURLString,
 98            [NSNumber numberWithBool:YES], kServerPromptUser,
 99            nil];
100
101  action = [KSUpdateAction actionWithUpdateInfo:info
102                                         runner:@"not nil"
103                                  userInitiated:NO];
104  STAssertNotNil(action, nil);
105  STAssertTrue([[action description] length] > 1, nil);
106
107  // Make sure the -wantsReboot method works correctly.
108  STAssertFalse([action wantsReboot], nil);
109  KSInstallAction *install = [[action actions] lastObject];
110  [[install outPipe] setContents:[NSNumber numberWithInt:KS_INSTALL_WANTS_REBOOT]];
111  STAssertTrue([action wantsReboot], nil);
112  [[install outPipe] setContents:[NSNumber numberWithInt:0]];
113  STAssertFalse([action wantsReboot], nil);
114  [[install outPipe] setContents:[NSNumber numberWithInt:1]];
115  STAssertFalse([action wantsReboot], nil);
116}
117
118- (void)loopUntilDone:(KSAction *)action {
119  int count = 10;
120  while ([action isRunning] && (count > 0)) {
121    NSDate *quick = [NSDate dateWithTimeIntervalSinceNow:0.2];
122    [[NSRunLoop currentRunLoop] runUntilDate:quick];
123    count--;
124  }
125  STAssertFalse([action isRunning], nil);
126}
127
128// Return a happy action which, if executed, will perform a successful update.
129- (KSUpdateAction *)happyAction {
130  id<KSCommandRunner> runner = [KSTaskCommandRunner commandRunner];
131  STAssertNotNil(runner, nil);
132
133  NSURL *url = [NSURL fileURLWithPath:successDMGPath_];
134  NSData *data = [NSData dataWithContentsOfFile:successDMGPath_];
135  NSData *dhash = [data SHA1Hash];
136  NSString *hash = [GTMBase64 stringByEncodingData:dhash];
137  NSString *name = [NSString stringWithFormat:@"KSUpdateActionUnitTest-%x",
138                             geteuid()];
139  unsigned long long size =
140    [[[NSFileManager defaultManager] fileAttributesAtPath:successDMGPath_
141                                             traverseLink:NO] fileSize];
142
143  KSUpdateInfo *info =
144    [NSDictionary dictionaryWithObjectsAndKeys:
145                    name, kServerProductID,
146                  url, kServerCodebaseURL,
147                       [NSNumber numberWithInt:size], kServerCodeSize,
148                  hash, kServerCodeHash,
149                  nil];
150
151  KSUpdateAction *action = nil;
152  action = [KSUpdateAction actionWithUpdateInfo:info
153                                         runner:runner
154                                  userInitiated:NO];
155  STAssertNotNil(action, nil);
156  return action;
157}
158
159- (void)testSuccessfullUpdate {
160  KSUpdateAction *action = [self happyAction];
161
162  SuccessDelegate *delegate = [[[SuccessDelegate alloc] init] autorelease];
163  // Create an action processor and run the action
164  KSActionProcessor *ap = [[[KSActionProcessor alloc] initWithDelegate:delegate] autorelease];
165  STAssertNotNil(ap, nil);
166
167  [ap enqueueAction:action];
168  [ap startProcessing];
169
170  [self loopUntilDone:action];
171
172  STAssertFalse([action isRunning], nil);
173  STAssertTrue([delegate wasSuccessful], nil);
174  STAssertFalse([action wantsReboot], nil);
175  STAssertEqualObjects([action returnCode], [NSNumber numberWithInt:0], nil);
176}
177
178- (void)testFailedUpdate {
179  id<KSCommandRunner> runner = [KSTaskCommandRunner commandRunner];
180  STAssertNotNil(runner, nil);
181
182  NSURL *url = [NSURL fileURLWithPath:failureDMGPath_];
183  NSData *data = [NSData dataWithContentsOfFile:failureDMGPath_];
184  NSData *dhash = [data SHA1Hash];
185  NSString *hash = [GTMBase64 stringByEncodingData:dhash];
186  NSString *name = [NSString stringWithFormat:@"KSUpdateActionUnitTest-%x",
187                    geteuid()];
188  unsigned long long size =
189  [[[NSFileManager defaultManager] fileAttributesAtPath:failureDMGPath_
190                                           traverseLink:NO] fileSize];
191
192  KSUpdateInfo *info =
193  [NSDictionary dictionaryWithObjectsAndKeys:
194   name, kServerProductID,
195   url, kServerCodebaseURL,
196   [NSNumber numberWithInt:size], kServerCodeSize,
197   hash, kServerCodeHash,
198   nil];
199
200  KSUpdateAction *action = nil;
201  action = [KSUpdateAction actionWithUpdateInfo:info
202                                         runner:runner
203                                  userInitiated:NO];
204  STAssertNotNil(action, nil);
205
206  SuccessDelegate *delegate = [[[SuccessDelegate alloc] init] autorelease];
207  // Create an action processor and run the action
208  KSActionProcessor *ap = [[[KSActionProcessor alloc] initWithDelegate:delegate] autorelease];
209  STAssertNotNil(ap, nil);
210
211  [ap enqueueAction:action];
212  [ap startProcessing];
213
214  [self loopUntilDone:action];
215
216  STAssertFalse([action isRunning], nil);
217  STAssertFalse([delegate wasSuccessful], nil);
218  STAssertFalse([action wantsReboot], nil);
219  STAssertEqualObjects([action returnCode], [NSNumber numberWithInt:11], nil);
220}
221
222- (void)testFailedDownload {
223  id<KSCommandRunner> runner = [KSTaskCommandRunner commandRunner];
224  STAssertNotNil(runner, nil);
225
226  NSString *path = @"/path/to/fake/file/blah/blah/blah";
227  NSURL *url = [NSURL fileURLWithPath:path];
228  NSString *hash = @"zzz";
229  NSString *name = [NSString stringWithFormat:@"KSUpdateActionUnitTest-%x",
230                    geteuid()];
231  unsigned long long size = 1;
232
233  KSUpdateInfo *info =
234  [NSDictionary dictionaryWithObjectsAndKeys:
235   name, kServerProductID,
236   url, kServerCodebaseURL,
237   [NSNumber numberWithInt:size], kServerCodeSize,
238   hash, kServerCodeHash,
239   nil];
240
241  KSUpdateAction *action = nil;
242  action = [KSUpdateAction actionWithUpdateInfo:info
243                                         runner:runner
244                                  userInitiated:NO];
245  STAssertNotNil(action, nil);
246
247  SuccessDelegate *delegate = [[[SuccessDelegate alloc] init] autorelease];
248  // Create an action processor and run the action
249  KSActionProcessor *ap = [[[KSActionProcessor alloc] initWithDelegate:delegate] autorelease];
250  STAssertNotNil(ap, nil);
251
252  [ap enqueueAction:action];
253  [ap startProcessing];
254
255  [self loopUntilDone:action];
256
257  STAssertFalse([action isRunning], nil);
258  STAssertFalse([delegate wasSuccessful], nil);
259  STAssertFalse([action wantsReboot], nil);
260  STAssertNil([action returnCode], nil);
261}
262
263// Be sure we implement the progress protocol
264- (void)runningAction:(KSUpdateAction *)action
265             progress:(NSNumber *)progress {
266  [progressArray_ addObject:progress];
267}
268
269@end