PageRenderTime 115ms CodeModel.GetById 2ms app.highlight 108ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://macfuse.googlecode.com/
Objective C | 650 lines | 444 code | 144 blank | 62 comment | 10 complexity | 56407cf86f21cd61f8585ab50404e429 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 "KSUpdateEngine.h"
 17#import "KSUpdateEngine+Configuration.h"
 18#import "KSTicketStore.h"
 19#import "KSTicket.h"
 20#import "KSCommandRunner.h"
 21#import "KSExistenceChecker.h"
 22#import "KSUUID.h"
 23#import "KSFrameworkStats.h"
 24
 25
 26@interface KSUpdateEngineTest : SenTestCase {
 27 @private
 28  NSString *storePath_;
 29  NSURL *serverSuccessPlistURL_;
 30  NSURL *serverFailurePlistURL_;
 31}
 32@end
 33
 34
 35@interface UpdateEngineDelegate : NSObject {
 36 @private
 37  BOOL finished_;
 38  BOOL updateFailed_;
 39  BOOL engineFailed_;
 40  NSMutableArray *progressArray_;
 41}
 42
 43- (BOOL)isFinished;
 44- (BOOL)updateFailed;
 45- (BOOL)engineFailed;
 46- (NSArray *)progressArray;
 47
 48@end
 49
 50@implementation UpdateEngineDelegate
 51
 52- (id)init {
 53  if ((self = [super init])) {
 54    progressArray_ = [[NSMutableArray array] retain];
 55  }
 56  return self;
 57}
 58
 59- (void)dealloc {
 60  [progressArray_ release];
 61  [super dealloc];
 62}
 63
 64- (BOOL)isFinished {
 65  return finished_;
 66}
 67
 68- (BOOL)updateFailed{
 69  return updateFailed_;
 70}
 71
 72- (BOOL)engineFailed {
 73  return engineFailed_;
 74}
 75
 76- (id<KSCommandRunner>)commandRunnerForEngine:(KSUpdateEngine *)engine {
 77  return [KSTaskCommandRunner commandRunner];
 78}
 79
 80- (void)engine:(KSUpdateEngine *)engine
 81       running:(KSUpdateInfo *)updateInfo
 82      progress:(NSNumber *)progress {
 83  [progressArray_ addObject:progress];
 84}
 85
 86- (NSArray *)progressArray {
 87  return progressArray_;
 88}
 89
 90
 91- (void)engine:(KSUpdateEngine *)engine
 92      finished:(KSUpdateInfo *)updateInfo
 93    wasSuccess:(BOOL)wasSuccess
 94   wantsReboot:(BOOL)wantsReboot {
 95  if (wasSuccess == NO)
 96    updateFailed_ = YES;
 97}
 98
 99- (void)engineFinished:(KSUpdateEngine *)engine wasSuccess:(BOOL)wasSuccess {
100  finished_ = YES;
101  engineFailed_ = !wasSuccess;
102}
103
104- (NSDictionary *)engine:(KSUpdateEngine *)engine
105       statsForProductID:(NSString *)productID {
106  return [NSDictionary dictionary];
107}
108
109@end  // UpdateEngineDelegate
110
111
112// Helper class to serve as a KSUpdateEngine delegate and record all
113// the delegate methods that it receives.
114@interface CallbackTracker : NSObject {
115 @private
116  NSMutableArray *methods_;
117}
118
119- (NSArray *)methods;
120
121@end
122
123@implementation CallbackTracker
124
125- (id)init {
126  if ((self = [super init]))
127    methods_ = [[NSMutableArray alloc] init];
128  return self;
129}
130
131- (void)dealloc {
132  [methods_ release];
133  [super dealloc];
134}
135
136- (NSArray *)methods {
137  return methods_;
138}
139
140- (NSArray *)engine:(KSUpdateEngine *)engine
141shouldPrefetchProducts:(NSArray *)products {
142  [methods_ addObject:NSStringFromSelector(_cmd)];
143  return products;
144}
145
146- (NSArray *)engine:(KSUpdateEngine *)engine
147shouldSilentlyUpdateProducts:(NSArray *)products {
148  [methods_ addObject:NSStringFromSelector(_cmd)];
149  return products;
150}
151
152- (id<KSCommandRunner>)commandRunnerForEngine:(KSUpdateEngine *)engine {
153  [methods_ addObject:NSStringFromSelector(_cmd)];
154  return nil;
155}
156
157- (void)engine:(KSUpdateEngine *)engine
158      starting:(KSUpdateInfo *)updateInfo {
159  [methods_ addObject:NSStringFromSelector(_cmd)];
160}
161
162- (void)engine:(KSUpdateEngine *)engine
163      finished:(KSUpdateInfo *)updateInfo
164    wasSuccess:(BOOL)wasSuccess
165   wantsReboot:(BOOL)wantsReboot {
166  [methods_ addObject:NSStringFromSelector(_cmd)];
167}
168
169- (NSArray *)engine:(KSUpdateEngine *)engine
170 shouldUpdateProducts:(NSArray *)products {
171  [methods_ addObject:NSStringFromSelector(_cmd)];
172  return products;
173}
174
175- (NSDictionary *)engine:(KSUpdateEngine *)engine
176       statsForProductID:(NSString *)productID {
177  [methods_ addObject:NSStringFromSelector(_cmd)];
178  return nil;  // Make sure a nil stat directory doesn't cause an exception.
179}
180
181@end  // CallbackTracker
182
183
184// Non-public methods that we want to call for testing.
185@interface KSUpdateEngine (UpdateEngineFriend)
186- (void)processingStarted:(KSActionProcessor *)processor;
187- (void)processingStopped:(KSActionProcessor *)processor;
188@end
189
190
191// This delegate is bad because it throws an exception on every call. We throw
192// NSStrings instead of NSExceptions to make sure we don't accidentally assume
193// that NSExceptions are the only objects that can be thrown.
194@interface BadDelegate : NSObject
195// Nothing
196@end
197
198@implementation BadDelegate
199
200- (void)engineStarted:(KSUpdateEngine *)engine {
201  @throw @"blah";
202}
203
204- (NSDictionary *)engine:(KSUpdateEngine *)engine
205       statsForProductID:(NSString *)productID {
206  @throw @"blah";
207}
208
209- (void)engineFinished:(KSUpdateEngine *)engine wasSuccess:(BOOL)wasSuccess {
210  @throw @"blah";
211}
212
213- (NSArray *)engine:(KSUpdateEngine *)engine
214shouldPrefetchProducts:(NSArray *)products {
215  @throw @"blah";
216}
217
218- (NSArray *)engine:(KSUpdateEngine *)engine
219shouldSilentlyUpdateProducts:(NSArray *)products {
220  @throw @"blah";
221}
222
223- (id<KSCommandRunner>)commandRunnerForEngine:(KSUpdateEngine *)engine {
224  @throw @"blah";
225}
226
227- (void)engine:(KSUpdateEngine *)engine
228      starting:(KSUpdateInfo *)updateInfo {
229  @throw @"blah";
230}
231
232- (void)engine:(KSUpdateEngine *)engine
233      finished:(KSUpdateInfo *)updateInfo
234    wasSuccess:(BOOL)wasSuccess
235   wantsReboot:(BOOL)wantsReboot {
236  @throw @"blah";
237}
238
239- (NSArray *)engine:(KSUpdateEngine *)engine
240 shouldUpdateProducts:(NSArray *)products {
241  @throw @"blah";
242}
243
244- (void)engine:(KSUpdateEngine *)engine
245       running:(KSUpdateInfo *)updateInfo
246      progress:(NSNumber *)progress {
247  @throw @"blah";
248}
249
250@end  // BadDelegate
251
252
253@implementation KSUpdateEngineTest
254
255- (void)setUp {
256  // Generate a unique temp file name
257  storePath_ = [[NSString stringWithFormat:@"/tmp/KSUpdateEngineTest.%@",
258                 [KSUUID uuidString]] retain];
259  STAssertNotNil(storePath_, nil);
260
261  NSBundle *mainBundle = [NSBundle bundleForClass:[self class]];
262
263  // Get the path to a successful server plist response
264  NSString *path = [mainBundle pathForResource:@"ServerSuccess"
265                                        ofType:@"plist"];
266  STAssertNotNil(path, nil);
267  serverSuccessPlistURL_ = [[NSURL fileURLWithPath:path] retain];
268  STAssertNotNil(serverSuccessPlistURL_, nil);
269
270  // Copy the DMG referenced in the ServerSuccess.plist file to /tmp/
271  NSString *dmg = [mainBundle pathForResource:@"Test-SUCCESS" ofType:@"dmg"];
272  STAssertNotNil(path, nil);
273  [[NSFileManager defaultManager] removeFileAtPath:@"/tmp/Test-SUCCESS.dmg"
274                                           handler:nil];
275  BOOL copied = [[NSFileManager defaultManager] copyPath:dmg
276                                                  toPath:@"/tmp/Test-SUCCESS.dmg"
277                                                 handler:nil];
278  STAssertTrue(copied, nil);
279
280  // Now, do the same thing for the "failure" XML and DMG
281  path = [mainBundle pathForResource:@"ServerFailure" ofType:@"plist"];
282  STAssertNotNil(path, nil);
283  serverFailurePlistURL_ = [[NSURL fileURLWithPath:path] retain];
284  STAssertNotNil(serverFailurePlistURL_, nil);
285
286  dmg = [mainBundle pathForResource:@"Test-FAILURE" ofType:@"dmg"];
287  STAssertNotNil(path, nil);
288  [[NSFileManager defaultManager] removeFileAtPath:@"/tmp/Test-FAILURE.dmg" handler:nil];
289  copied = [[NSFileManager defaultManager] copyPath:dmg
290                                             toPath:@"/tmp/Test-FAILURE.dmg"
291                                            handler:nil];
292  STAssertTrue(copied, nil);
293
294  [@"" writeToFile:storePath_ atomically:YES];
295  [KSUpdateEngine setDefaultTicketStorePath:storePath_];
296}
297
298- (void)tearDown {
299  [KSUpdateEngine setDefaultTicketStorePath:nil];
300  [[NSFileManager defaultManager] removeFileAtPath:storePath_ handler:nil];
301  NSString *lock = [storePath_ stringByAppendingPathExtension:@"lock"];
302  [[NSFileManager defaultManager] removeFileAtPath:lock handler:nil];
303  [[NSFileManager defaultManager] removeFileAtPath:@"/tmp/Test-SUCCESS.dmg" handler:nil];
304  [[NSFileManager defaultManager] removeFileAtPath:@"/tmp/Test-FAILURE.dmg" handler:nil];
305  [storePath_ release];
306  [serverSuccessPlistURL_ release];
307  [serverFailurePlistURL_ release];
308}
309
310- (void)loopUntilDone:(UpdateEngineDelegate *)delegate {
311  int count = 50;
312  while (![delegate isFinished] && (count > 0)) {
313    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
314    count--;
315  }
316  STAssertTrue(count > 0, nil);  // make sure we didn't time out
317}
318
319- (void)testCreation {
320  KSUpdateEngine *engine = nil;
321
322  engine = [[[KSUpdateEngine alloc] init] autorelease];
323  STAssertNil(engine, nil);
324
325  engine = [KSUpdateEngine engineWithDelegate:nil];
326  STAssertNotNil(engine, nil);
327
328  STAssertTrue([[engine description] length] > 1, nil);
329  STAssertNotNil([engine ticketStore], nil);
330  STAssertNil([engine delegate], nil);
331  [engine setDelegate:@"not nil"];
332  STAssertNotNil([engine delegate], nil);
333  STAssertNil([engine statsCollection], nil);
334
335  [KSUpdateEngine setDefaultTicketStorePath:nil];  // Reset to default
336  NSString *defaultPath = [KSUpdateEngine defaultTicketStorePath];
337  STAssertNil(defaultPath, nil);
338  [KSUpdateEngine setDefaultTicketStorePath:@"foo"];
339  STAssertEqualObjects([KSUpdateEngine defaultTicketStorePath],
340                       @"foo", nil);
341  [KSUpdateEngine setDefaultTicketStorePath:nil];  // Reset to default
342  STAssertEqualObjects([KSUpdateEngine defaultTicketStorePath],
343                       defaultPath, nil);
344}
345
346- (void)testDelegateCallbacks {
347  CallbackTracker *tracker = [[[CallbackTracker alloc] init] autorelease];
348  STAssertNotNil(tracker, nil);
349
350  KSUpdateEngine *engine = [KSUpdateEngine engineWithDelegate:tracker];
351  STAssertNotNil(engine, nil);
352
353  STAssertNotNil([engine delegate], nil);
354  STAssertEqualObjects([engine delegate], tracker, nil);
355
356  // Call all the delegate methods.
357  [engine action:nil shouldPrefetchProducts:nil];
358  [engine action:nil shouldSilentlyUpdateProducts:nil];
359  [engine commandRunnerForAction:nil];
360  [engine action:nil shouldUpdateProducts:nil];
361  [engine action:nil starting:nil];
362  [engine action:nil finished:nil wasSuccess:NO wantsReboot:NO];
363
364  NSArray *expect = [NSArray arrayWithObjects:
365                     @"engine:shouldPrefetchProducts:",
366                     @"engine:shouldSilentlyUpdateProducts:",
367                     @"commandRunnerForEngine:",
368                     @"engine:shouldUpdateProducts:",
369                     @"engine:starting:",
370                     @"engine:finished:wasSuccess:wantsReboot:",
371                     nil];
372
373  STAssertEqualObjects([tracker methods], expect, nil);
374
375  // Make sure that if the delegate does not respond to the
376  // commandRunnerForEngine: selector, we get back a default
377  // command runner.
378  engine = [KSUpdateEngine engineWithDelegate:nil];
379  id<KSCommandRunner> runner = [engine commandRunnerForAction:nil];
380  STAssertNotNil(runner, nil);
381}
382
383- (void)testFailedUpdate {
384  KSTicketStore *store = [KSTicketStore ticketStoreWithPath:storePath_];
385  STAssertNotNil(store, nil);
386  STAssertTrue([[store tickets] count] == 0, nil);
387
388  KSExistenceChecker *xc = [KSPathExistenceChecker checkerWithPath:@"/"];
389  KSTicket *t = [KSTicket ticketWithProductID:@"COM.GOOGLE.UPDATEENGINE.KSUPDATEENGINE_TEST"
390                                      version:@"1.0"
391                             existenceChecker:xc
392                                    serverURL:serverFailurePlistURL_];
393
394  STAssertTrue([store storeTicket:t], nil);
395
396  UpdateEngineDelegate *delegate = [[[UpdateEngineDelegate alloc] init] autorelease];
397  KSUpdateEngine *engine = nil;
398  engine = [KSUpdateEngine engineWithTicketStore:store delegate:delegate];
399  STAssertNotNil(engine, nil);
400
401  KSStatsCollection *stats = [KSStatsCollection statsCollectionWithPath:@"/dev/null"
402                                                        autoSynchronize:NO];
403  STAssertTrue([stats count] == 0, nil);
404  [engine setStatsCollection:stats];
405
406  [engine updateAllProducts];
407
408  [self loopUntilDone:delegate];
409
410  STAssertFalse([engine isUpdating], nil);
411
412  // Make sure the update failed
413  STAssertTrue([delegate updateFailed], nil);
414  // But UpdateEngine as a whole should have succeeded
415  STAssertFalse([delegate engineFailed], nil);
416
417  STAssertTrue([stats count] > 0, nil);
418  [engine setStatsCollection:nil];
419
420  // Verify that a few stats are present and accurate.
421  STAssertEqualObjects([stats numberForStat:kStatChecks], [NSNumber numberWithInt:1], nil);
422  STAssertEqualObjects([stats numberForStat:kStatDownloads], [NSNumber numberWithInt:1], nil);
423  STAssertEqualObjects([stats numberForStat:kStatTickets], [NSNumber numberWithInt:1], nil);
424  STAssertEqualObjects([stats numberForStat:kStatValidTickets], [NSNumber numberWithInt:1], nil);
425
426  NSString *statKey = KSMakeProductStatKey(@"COM.GOOGLE.UPDATEENGINE.KSUPDATEENGINE_TEST", kStatInstallRC);
427  STAssertEqualObjects([stats numberForStat:statKey], [NSNumber numberWithInt:11], nil);
428}
429
430- (void)testUpdateFromGoodURL {
431  KSTicketStore *store = [KSTicketStore ticketStoreWithPath:storePath_];
432  STAssertNotNil(store, nil);
433
434  KSExistenceChecker *xc = [KSPathExistenceChecker checkerWithPath:@"/"];
435  KSTicket *t = [KSTicket ticketWithProductID:@"COM.GOOGLE.UPDATEENGINE.KSUPDATEENGINE_TEST"
436                                      version:@"1.0"
437                             existenceChecker:xc
438                                    serverURL:serverSuccessPlistURL_];
439  STAssertTrue([store storeTicket:t], nil);
440
441  UpdateEngineDelegate *delegate = [[[UpdateEngineDelegate alloc] init] autorelease];
442  KSUpdateEngine *engine = nil;
443  engine = [KSUpdateEngine engineWithTicketStore:store delegate:delegate];
444  STAssertNotNil(engine, nil);
445
446  KSStatsCollection *stats = [KSStatsCollection statsCollectionWithPath:@"/dev/null"
447                                                        autoSynchronize:NO];
448  [engine setStatsCollection:stats];
449
450  [engine updateAllProducts];
451
452  [self loopUntilDone:delegate];
453
454  STAssertFalse([engine isUpdating], nil);
455
456  // Make sure the update succeeded
457  STAssertFalse([delegate updateFailed], nil);
458  // And that UpdateEngine as a whole succeeded
459  STAssertFalse([delegate engineFailed], nil);
460
461  // And that we got legit progress:
462  NSArray *progress = [delegate progressArray];
463  STAssertTrue([progress count] >= 2, nil);
464
465  // No guarantees about these two but they just make sense
466  STAssertTrue([[progress objectAtIndex:0]
467                 isEqual:[NSNumber numberWithFloat:0.0]], nil);
468  STAssertTrue([[progress lastObject]
469                 isEqual:[NSNumber numberWithFloat:1.0]], nil);
470
471  // Make sure progress never goes backwards
472  float f = 0.0;
473  NSEnumerator *aenum = [progress objectEnumerator];
474  NSNumber *num = nil;
475  while ((num = [aenum nextObject]) != nil) {
476    STAssertTrue([num floatValue] >= f, nil);
477    f = [num floatValue];
478  }
479
480
481  STAssertTrue([stats count] > 0, nil);
482  [engine setStatsCollection:nil];
483
484  // Verify that a few stats are present and accurate.
485  STAssertEqualObjects([stats numberForStat:kStatChecks], [NSNumber numberWithInt:1], nil);
486  STAssertEqualObjects([stats numberForStat:kStatDownloads], [NSNumber numberWithInt:1], nil);
487  STAssertEqualObjects([stats numberForStat:kStatTickets], [NSNumber numberWithInt:1], nil);
488  STAssertEqualObjects([stats numberForStat:kStatValidTickets], [NSNumber numberWithInt:1], nil);
489
490  NSString *statKey = KSMakeProductStatKey(@"COM.GOOGLE.UPDATEENGINE.KSUPDATEENGINE_TEST", kStatInstallRC);
491  STAssertEqualObjects([stats numberForStat:statKey], [NSNumber numberWithInt:0], nil);
492
493  //
494  // Make sure we can update a single product ID
495  //
496  delegate = [[[UpdateEngineDelegate alloc] init] autorelease];
497  [engine setDelegate:delegate];
498
499  [engine updateProductWithProductID:@"COM.GOOGLE.UPDATEENGINE.KSUPDATEENGINE_TEST"];
500  [self loopUntilDone:delegate];
501
502  STAssertFalse([engine isUpdating], nil);
503
504  // Make sure the update succeeded
505  STAssertFalse([delegate updateFailed], nil);
506  // And that UpdateEngine as a whole succeeded
507  STAssertFalse([delegate engineFailed], nil);
508}
509
510- (void)testFailedCheck {
511  KSTicketStore *store = [KSTicketStore ticketStoreWithPath:storePath_];
512  STAssertNotNil(store, nil);
513
514  //
515  // First test using 1 ticket with an unreachable URL
516  //
517
518  KSExistenceChecker *xc = [KSPathExistenceChecker checkerWithPath:@"/"];
519  KSTicket *t = [KSTicket ticketWithProductID:@"com.google.foo"
520                                      version:@"1.0"
521                             existenceChecker:xc
522                                    serverURL:[NSURL URLWithString:@"https://asdfasdf.tools.google.com"]];
523
524  STAssertTrue([store storeTicket:t], nil);
525
526  UpdateEngineDelegate *delegate = [[[UpdateEngineDelegate alloc] init] autorelease];
527  KSUpdateEngine *engine = nil;
528  engine = [KSUpdateEngine engineWithTicketStore:store delegate:delegate];
529  STAssertNotNil(engine, nil);
530
531  [engine updateAllProducts];
532  [self loopUntilDone:delegate];
533
534  STAssertFalse([engine isUpdating], nil);
535
536  // But UpdateEngine as a whole should have succeeded
537  STAssertTrue([delegate engineFailed], nil);
538
539
540  //
541  // Second, test with multiple tickets with an unreachable URL
542  //
543
544  t = [KSTicket ticketWithProductID:@"com.google.foo1"
545                            version:@"1.0"
546                   existenceChecker:xc
547                          serverURL:[NSURL URLWithString:@"https://zas4zf4.tools.google.com"]];
548
549  STAssertTrue([store storeTicket:t], nil);
550
551  delegate = [[[UpdateEngineDelegate alloc] init] autorelease];
552  engine = [KSUpdateEngine engineWithTicketStore:store delegate:delegate];
553  STAssertNotNil(engine, nil);
554
555  [engine updateAllProducts];
556  [self loopUntilDone:delegate];
557
558  STAssertFalse([engine isUpdating], nil);
559
560  // But UpdateEngine as a whole should have succeeded
561  STAssertTrue([delegate engineFailed], nil);
562
563  //
564  // Third, add one ticket with a GOOD URL, and the check should succeed.
565  //
566
567  t = [KSTicket ticketWithProductID:@"com.google.foo2"
568                            version:@"1.0"
569                   existenceChecker:xc
570                          serverURL:[NSURL URLWithString:@"file:///etc/passwd"]];
571
572  STAssertTrue([store storeTicket:t], nil);
573
574  delegate = [[[UpdateEngineDelegate alloc] init] autorelease];
575  engine = [KSUpdateEngine engineWithTicketStore:store delegate:delegate];
576  STAssertNotNil(engine, nil);
577
578  [engine updateAllProducts];
579  [self loopUntilDone:delegate];
580
581  STAssertFalse([engine isUpdating], nil);
582
583  //
584  // Fourth, try updating a product with no corresponding ticket.
585  //
586  [engine updateProductWithProductID:@"lotus blossom"];
587
588  // But UpdateEngine as a whole should have succeeded
589  STAssertFalse([delegate engineFailed], nil);  // <-- This is the diff
590}
591
592- (void)testWithBadDelegate {
593  KSTicketStore *store = [KSTicketStore ticketStoreWithPath:storePath_];
594  STAssertNotNil(store, nil);
595  KSExistenceChecker *xc = [KSPathExistenceChecker checkerWithPath:@"/"];
596  // Make sure there's at least one ticket, so that the statsForProductID:
597  // delegate will be called.
598  KSTicket *t;
599  t = [KSTicket ticketWithProductID:@"com.google.foo3"
600                            version:@"1.0"
601                   existenceChecker:xc
602                          serverURL:[NSURL URLWithString:@"file:///etc/passwd"]];
603  STAssertTrue([store storeTicket:t], nil);
604
605  BadDelegate *delegate = [[[BadDelegate alloc] init] autorelease];
606  KSUpdateEngine *engine =
607    [KSUpdateEngine engineWithTicketStore:store delegate:delegate];
608  STAssertNotNil(engine, nil);
609
610  [engine processingStarted:nil];
611  [engine processingStopped:nil];
612  [engine updateAllProducts];
613
614  // Call all the delegate methods.
615
616  NSArray *products = [NSArray array];
617
618  STAssertEqualObjects([engine action:nil shouldPrefetchProducts:products],
619                       products, nil);
620
621  STAssertEqualObjects([engine action:nil shouldSilentlyUpdateProducts:products],
622                       products, nil);
623
624  STAssertNil([engine commandRunnerForAction:nil], nil);
625
626  STAssertEqualObjects([engine action:nil shouldUpdateProducts:nil],
627                       nil, nil);
628
629  // void returns
630  [engine action:nil starting:nil];
631  [engine action:nil finished:nil wasSuccess:NO wantsReboot:NO];
632  [engine action:nil running:nil progress:nil];
633
634  // Simply make sure we got this far w/o letting an exception through
635  STAssertTrue(YES, nil);
636}
637
638- (void)testParams {
639  KSTicketStore *store = [KSTicketStore ticketStoreWithPath:storePath_];
640  KSUpdateEngine *engine = [KSUpdateEngine engineWithTicketStore:store
641                                                        delegate:nil];
642  NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
643                                       @"oop", @"ack",
644                                       @"bill th", @"e cat", nil];
645  [engine setParams:params];
646  NSDictionary *engineParams = [engine valueForKey:@"params_"];
647  STAssertTrue([params isEqualToDictionary:engineParams], nil);
648}
649
650@end