~nchohan/appscale/zk3.3.4

831 by Chris Bunch
refactored tests to use flexmock, and removed exception writing to ~/.appscale, since we weren't using it anyways and it prevented running tests on non-AppScale machines
1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
<html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
3
  <head>
4
    <title>/home/cgb/clients/main/main-cgb-research/Neptune/task_engine_google_app_engine.rb</title>
5
    <link href="screen.css" media="all" rel="stylesheet" type="text/css" />
6
    <link href="print.css" media="print" rel="stylesheet" type="text/css" />
7
    
8
    <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
9
    <script type="text/javascript" src="rcov.js"></script>
10
  </head>
11
  <body>
12
    <h1>Test C0 Coverage Information - RCov</h1>
13
    <h2>/home/cgb/clients/main/main-cgb-research/Neptune/task_engine_google_app_engine.rb</h2>
14
15
    
16
17
    <div class="report_table_wrapper">
18
      <table class='report' id='report_table'>
19
        <thead>
20
          <tr>
21
            <th class="left_align">Name</th>
22
            <th class="right_align">Total Lines</th>
23
            <th class="right_align">Lines of Code</th>
24
            <th class="left_align">Total Coverage</th>
25
            <th class="left_align">Code Coverage</th>
26
          </tr>
27
        </thead>
28
        <tbody>
29
          <tr>
30
            <td class="left_align"><a href="-home-cgb-clients-main-main-cgb-research-Neptune-task_engine_google_app_engine_rb.html">/home/cgb/clients/main/main-cgb-research/Neptune/task_engine_google_app_engine.rb</a></td>
31
            <td class='right_align'><tt>122</tt></td>
32
            <td class='right_align'><tt>73</tt></td>
33
            <td class="left_align"><div class="percent_graph_legend"><tt class=''>31.15%</tt></div>
34
          <div class="percent_graph">
35
            <div class="covered" style="width:31px"></div>
36
            <div class="uncovered" style="width:69px"></div>
37
          </div></td>
38
            <td class="left_align"><div class="percent_graph_legend"><tt class=''>20.55%</tt></div>
39
          <div class="percent_graph">
40
            <div class="covered" style="width:21px"></div>
41
            <div class="uncovered" style="width:79px"></div>
42
          </div></td>
43
          </tr>
44
        </tbody>
45
      </table>
46
    </div>
47
    
48
    <h3>Key</h3>
49
    
50
    <div class="key"><pre><span class='marked'>Code reported as executed by Ruby looks like this...</span><span class='marked1'>and this: this line is also marked as covered.</span><span class='inferred'>Lines considered as run by rcov, but not reported by Ruby, look like this,</span><span class='inferred1'>and this: these lines were inferred by rcov (using simple heuristics).</span><span class='uncovered'>Finally, here's a line marked as not executed.</span></pre></div>
51
52
    <h3>Coverage Details</h3>
53
54
    <table class="details">
55
      <tbody>
56
        
57
          
58
          
59
          <tr class="inferred">
60
            <td><pre><a name="line1">1</a> # Programmer: Chris Bunch</pre></td>
61
          </tr>
62
        
63
          
64
          
65
          <tr class="inferred">
66
            <td><pre><a name="line2">2</a> </pre></td>
67
          </tr>
68
        
69
          
70
          
71
          <tr class="marked">
72
            <td><pre><a name="line3">3</a> require 'djinn'</pre></td>
73
          </tr>
74
        
75
          
76
          
77
          <tr class="marked">
78
            <td><pre><a name="line4">4</a> require 'task_engine'</pre></td>
79
          </tr>
80
        
81
          
82
          
83
          <tr class="inferred">
84
            <td><pre><a name="line5">5</a> </pre></td>
85
          </tr>
86
        
87
          
88
          
89
          <tr class="marked">
90
            <td><pre><a name="line6">6</a> require 'rubygems'</pre></td>
91
          </tr>
92
        
93
          
94
          
95
          <tr class="marked">
96
            <td><pre><a name="line7">7</a> require 'httparty'</pre></td>
97
          </tr>
98
        
99
          
100
          
101
          <tr class="inferred">
102
            <td><pre><a name="line8">8</a> </pre></td>
103
          </tr>
104
        
105
          
106
          
107
          <tr class="inferred">
108
            <td><pre><a name="line9">9</a> </pre></td>
109
          </tr>
110
        
111
          
112
          
113
          <tr class="marked">
114
            <td><pre><a name="line10">10</a> class GoogleAppEnginePushQueue</pre></td>
115
          </tr>
116
        
117
          
118
          
119
          <tr class="marked">
120
            <td><pre><a name="line11">11</a>   include HTTParty</pre></td>
121
          </tr>
122
        
123
          
124
          
125
          <tr class="inferred">
126
            <td><pre><a name="line12">12</a> end</pre></td>
127
          </tr>
128
        
129
          
130
          
131
          <tr class="inferred">
132
            <td><pre><a name="line13">13</a> </pre></td>
133
          </tr>
134
        
135
          
136
          
137
          <tr class="inferred">
138
            <td><pre><a name="line14">14</a> </pre></td>
139
          </tr>
140
        
141
          
142
          
143
          <tr class="marked">
144
            <td><pre><a name="line15">15</a> class TaskEngineGoogleAppEngine &lt; TaskEngine</pre></td>
145
          </tr>
146
        
147
          
148
          
149
          <tr class="marked">
150
            <td><pre><a name="line16">16</a>   attr_accessor :appid, :appcfg_cookies, :function</pre></td>
151
          </tr>
152
        
153
          
154
          
155
          <tr class="inferred">
156
            <td><pre><a name="line17">17</a> </pre></td>
157
          </tr>
158
        
159
          
160
          
161
          <tr class="marked">
162
            <td><pre><a name="line18">18</a>   def initialize(credentials)</pre></td>
163
          </tr>
164
        
165
          
166
          
167
          <tr class="uncovered">
168
            <td><pre><a name="line19">19</a>     if credentials.class != Hash</pre></td>
169
          </tr>
170
        
171
          
172
          
173
          <tr class="uncovered">
174
            <td><pre><a name="line20">20</a>       raise BadConfigurationException.new</pre></td>
175
          </tr>
176
        
177
          
178
          
179
          <tr class="uncovered">
180
            <td><pre><a name="line21">21</a>     end</pre></td>
181
          </tr>
182
        
183
          
184
          
185
          <tr class="uncovered">
186
            <td><pre><a name="line22">22</a> </pre></td>
187
          </tr>
188
        
189
          
190
          
191
          <tr class="uncovered">
192
            <td><pre><a name="line23">23</a>     if credentials['appid'].nil?</pre></td>
193
          </tr>
194
        
195
          
196
          
197
          <tr class="uncovered">
198
            <td><pre><a name="line24">24</a>       raise BadConfigurationException.new</pre></td>
199
          </tr>
200
        
201
          
202
          
203
          <tr class="uncovered">
204
            <td><pre><a name="line25">25</a>     end</pre></td>
205
          </tr>
206
        
207
          
208
          
209
          <tr class="uncovered">
210
            <td><pre><a name="line26">26</a>     @appid = credentials['appid']</pre></td>
211
          </tr>
212
        
213
          
214
          
215
          <tr class="uncovered">
216
            <td><pre><a name="line27">27</a> </pre></td>
217
          </tr>
218
        
219
          
220
          
221
          <tr class="uncovered">
222
            <td><pre><a name="line28">28</a>     if credentials['appcfg_cookies'].nil?</pre></td>
223
          </tr>
224
        
225
          
226
          
227
          <tr class="uncovered">
228
            <td><pre><a name="line29">29</a>       raise BadConfigurationException.new</pre></td>
229
          </tr>
230
        
231
          
232
          
233
          <tr class="uncovered">
234
            <td><pre><a name="line30">30</a>     end</pre></td>
235
          </tr>
236
        
237
          
238
          
239
          <tr class="uncovered">
240
            <td><pre><a name="line31">31</a>     @appcfg_cookies = credentials['appcfg_cookies']</pre></td>
241
          </tr>
242
        
243
          
244
          
245
          <tr class="uncovered">
246
            <td><pre><a name="line32">32</a> </pre></td>
247
          </tr>
248
        
249
          
250
          
251
          <tr class="uncovered">
252
            <td><pre><a name="line33">33</a>     if credentials['function'].nil?</pre></td>
253
          </tr>
254
        
255
          
256
          
257
          <tr class="uncovered">
258
            <td><pre><a name="line34">34</a>       raise BadConfigurationException.new</pre></td>
259
          </tr>
260
        
261
          
262
          
263
          <tr class="uncovered">
264
            <td><pre><a name="line35">35</a>     end</pre></td>
265
          </tr>
266
        
267
          
268
          
269
          <tr class="uncovered">
270
            <td><pre><a name="line36">36</a>     @function = credentials['function']</pre></td>
271
          </tr>
272
        
273
          
274
          
275
          <tr class="uncovered">
276
            <td><pre><a name="line37">37</a>   end</pre></td>
277
          </tr>
278
        
279
          
280
          
281
          <tr class="inferred">
282
            <td><pre><a name="line38">38</a> </pre></td>
283
          </tr>
284
        
285
          
286
          
287
          <tr class="inferred">
288
            <td><pre><a name="line39">39</a> </pre></td>
289
          </tr>
290
        
291
          
292
          
293
          <tr class="inferred">
294
            <td><pre><a name="line40">40</a>   # Uploading the application to Google App Engine takes a non-trivially</pre></td>
295
          </tr>
296
        
297
          
298
          
299
          <tr class="inferred">
300
            <td><pre><a name="line41">41</a>   # long amount of time, and since the application can be invoked multiple</pre></td>
301
          </tr>
302
        
303
          
304
          
305
          <tr class="inferred">
306
            <td><pre><a name="line42">42</a>   # times in a row, it's unnecessary to keep re-uploading the app. Thus,</pre></td>
307
          </tr>
308
        
309
          
310
          
311
          <tr class="inferred">
312
            <td><pre><a name="line43">43</a>   # we skip avoiding the app if we detect that it is the same app as our</pre></td>
313
          </tr>
314
        
315
          
316
          
317
          <tr class="inferred">
318
            <td><pre><a name="line44">44</a>   # app - identified by its file name and function.</pre></td>
319
          </tr>
320
        
321
          
322
          
323
          <tr class="marked">
324
            <td><pre><a name="line45">45</a>   def app_needs_uploading?(job_data)</pre></td>
325
          </tr>
326
        
327
          
328
          
329
          <tr class="uncovered">
330
            <td><pre><a name="line46">46</a>     Djinn.log_debug(&quot;seeing if app needs to be uploaded to App Engine&quot;)</pre></td>
331
          </tr>
332
        
333
          
334
          
335
          <tr class="uncovered">
336
            <td><pre><a name="line47">47</a> </pre></td>
337
          </tr>
338
        
339
          
340
          
341
          <tr class="uncovered">
342
            <td><pre><a name="line48">48</a>     # We're expecting to see the filename (minus the extension), a dot, and</pre></td>
343
          </tr>
344
        
345
          
346
          
347
          <tr class="uncovered">
348
            <td><pre><a name="line49">49</a>     # the function name (no parens).</pre></td>
349
          </tr>
350
        
351
          
352
          
353
          <tr class="uncovered">
354
            <td><pre><a name="line50">50</a>     extension = File.extname(job_data['@code'])</pre></td>
355
          </tr>
356
        
357
          
358
          
359
          <tr class="uncovered">
360
            <td><pre><a name="line51">51</a>     file = File.basename(job_data['@code'], extension)</pre></td>
361
          </tr>
362
        
363
          
364
          
365
          <tr class="uncovered">
366
            <td><pre><a name="line52">52</a>     expected = file + &quot;.&quot; + @function</pre></td>
367
          </tr>
368
        
369
          
370
          
371
          <tr class="uncovered">
372
            <td><pre><a name="line53">53</a> </pre></td>
373
          </tr>
374
        
375
          
376
          
377
          <tr class="uncovered">
378
            <td><pre><a name="line54">54</a>     # Oration builds apps with an /id route, that returns the file and</pre></td>
379
          </tr>
380
        
381
          
382
          
383
          <tr class="uncovered">
384
            <td><pre><a name="line55">55</a>     # function that will be executed. We can compare that against our</pre></td>
385
          </tr>
386
        
387
          
388
          
389
          <tr class="uncovered">
390
            <td><pre><a name="line56">56</a>     # file and function to see if they are the same (and thus if the app</pre></td>
391
          </tr>
392
        
393
          
394
          
395
          <tr class="uncovered">
396
            <td><pre><a name="line57">57</a>     # needs to be uploaded).</pre></td>
397
          </tr>
398
        
399
          
400
          
401
          <tr class="uncovered">
402
            <td><pre><a name="line58">58</a>     host = get_app_url(job_data)</pre></td>
403
          </tr>
404
        
405
          
406
          
407
          <tr class="uncovered">
408
            <td><pre><a name="line59">59</a>     begin</pre></td>
409
          </tr>
410
        
411
          
412
          
413
          <tr class="uncovered">
414
            <td><pre><a name="line60">60</a>       actual = GoogleAppEnginePushQueue.get(&quot;#{host}/id&quot;)</pre></td>
415
          </tr>
416
        
417
          
418
          
419
          <tr class="uncovered">
420
            <td><pre><a name="line61">61</a>     rescue NoMethodError  # if the host is down</pre></td>
421
          </tr>
422
        
423
          
424
          
425
          <tr class="uncovered">
426
            <td><pre><a name="line62">62</a>       actual = &quot;&quot;</pre></td>
427
          </tr>
428
        
429
          
430
          
431
          <tr class="uncovered">
432
            <td><pre><a name="line63">63</a>     end</pre></td>
433
          </tr>
434
        
435
          
436
          
437
          <tr class="uncovered">
438
            <td><pre><a name="line64">64</a> </pre></td>
439
          </tr>
440
        
441
          
442
          
443
          <tr class="uncovered">
444
            <td><pre><a name="line65">65</a>     Djinn.log_debug(&quot;expected is [#{expected}], actual is [#{actual}]&quot;)</pre></td>
445
          </tr>
446
        
447
          
448
          
449
          <tr class="uncovered">
450
            <td><pre><a name="line66">66</a>     if expected == actual</pre></td>
451
          </tr>
452
        
453
          
454
          
455
          <tr class="uncovered">
456
            <td><pre><a name="line67">67</a>       # then the app in App Engine is up to date, so don't upload a new</pre></td>
457
          </tr>
458
        
459
          
460
          
461
          <tr class="uncovered">
462
            <td><pre><a name="line68">68</a>       # version of the app</pre></td>
463
          </tr>
464
        
465
          
466
          
467
          <tr class="uncovered">
468
            <td><pre><a name="line69">69</a>       Djinn.log_debug(&quot;App is already in App Engine - don't upload it again&quot;)</pre></td>
469
          </tr>
470
        
471
          
472
          
473
          <tr class="uncovered">
474
            <td><pre><a name="line70">70</a>       return false</pre></td>
475
          </tr>
476
        
477
          
478
          
479
          <tr class="uncovered">
480
            <td><pre><a name="line71">71</a>     else</pre></td>
481
          </tr>
482
        
483
          
484
          
485
          <tr class="uncovered">
486
            <td><pre><a name="line72">72</a>       # then the app in App Engine isn't the same as this app, so</pre></td>
487
          </tr>
488
        
489
          
490
          
491
          <tr class="uncovered">
492
            <td><pre><a name="line73">73</a>       # do upload a new version of the app</pre></td>
493
          </tr>
494
        
495
          
496
          
497
          <tr class="uncovered">
498
            <td><pre><a name="line74">74</a>       Djinn.log_debug(&quot;App does not match App Engine version - upload it&quot;)</pre></td>
499
          </tr>
500
        
501
          
502
          
503
          <tr class="uncovered">
504
            <td><pre><a name="line75">75</a>       return true</pre></td>
505
          </tr>
506
        
507
          
508
          
509
          <tr class="uncovered">
510
            <td><pre><a name="line76">76</a>     end</pre></td>
511
          </tr>
512
        
513
          
514
          
515
          <tr class="uncovered">
516
            <td><pre><a name="line77">77</a>   end</pre></td>
517
          </tr>
518
        
519
          
520
          
521
          <tr class="inferred">
522
            <td><pre><a name="line78">78</a> </pre></td>
523
          </tr>
524
        
525
          
526
          
527
          <tr class="inferred">
528
            <td><pre><a name="line79">79</a> </pre></td>
529
          </tr>
530
        
531
          
532
          
533
          <tr class="marked">
534
            <td><pre><a name="line80">80</a>   def self.upload_app(job_data, app_location)</pre></td>
535
          </tr>
536
        
537
          
538
          
539
          <tr class="uncovered">
540
            <td><pre><a name="line81">81</a>     Djinn.log_debug(&quot;uploading app to app engine&quot;)</pre></td>
541
          </tr>
542
        
543
          
544
          
545
          <tr class="uncovered">
546
            <td><pre><a name="line82">82</a> </pre></td>
547
          </tr>
548
        
549
          
550
          
551
          <tr class="uncovered">
552
            <td><pre><a name="line83">83</a>     # to avoid having to get the user's email / password, we can get</pre></td>
553
          </tr>
554
        
555
          
556
          
557
          <tr class="uncovered">
558
            <td><pre><a name="line84">84</a>     # their appcfg_cookies file and put it in ~</pre></td>
559
          </tr>
560
        
561
          
562
          
563
          <tr class="uncovered">
564
            <td><pre><a name="line85">85</a>     remote = job_data[&quot;@appcfg_cookies&quot;]</pre></td>
565
          </tr>
566
        
567
          
568
          
569
          <tr class="uncovered">
570
            <td><pre><a name="line86">86</a>     local = File.expand_path(&quot;~&quot;)</pre></td>
571
          </tr>
572
        
573
          
574
          
575
          <tr class="uncovered">
576
            <td><pre><a name="line87">87</a>     Djinn.copy_file_to_dir(remote, local, job_data)</pre></td>
577
          </tr>
578
        
579
          
580
          
581
          <tr class="uncovered">
582
            <td><pre><a name="line88">88</a> </pre></td>
583
          </tr>
584
        
585
          
586
          
587
          <tr class="uncovered">
588
            <td><pre><a name="line89">89</a>     # TODO(cgb) - check for return val here</pre></td>
589
          </tr>
590
        
591
          
592
          
593
          <tr class="uncovered">
594
            <td><pre><a name="line90">90</a>     appcfg = &quot;/root/appscale/AppServer/appcfg.py&quot;</pre></td>
595
          </tr>
596
        
597
          
598
          
599
          <tr class="uncovered">
600
            <td><pre><a name="line91">91</a>     appid = job_data[&quot;@appid&quot;]</pre></td>
601
          </tr>
602
        
603
          
604
          
605
          <tr class="uncovered">
606
            <td><pre><a name="line92">92</a>     Djinn.log_run(&quot;#{appcfg} update #{app_location} -A #{appid}&quot;)</pre></td>
607
          </tr>
608
        
609
          
610
          
611
          <tr class="uncovered">
612
            <td><pre><a name="line93">93</a>   end</pre></td>
613
          </tr>
614
        
615
          
616
          
617
          <tr class="inferred">
618
            <td><pre><a name="line94">94</a> </pre></td>
619
          </tr>
620
        
621
          
622
          
623
          <tr class="inferred">
624
            <td><pre><a name="line95">95</a> </pre></td>
625
          </tr>
626
        
627
          
628
          
629
          <tr class="marked">
630
            <td><pre><a name="line96">96</a>   def upload_app(job_data, app_location)</pre></td>
631
          </tr>
632
        
633
          
634
          
635
          <tr class="uncovered">
636
            <td><pre><a name="line97">97</a>     Djinn.log_debug(&quot;uploading app to app engine&quot;)</pre></td>
637
          </tr>
638
        
639
          
640
          
641
          <tr class="uncovered">
642
            <td><pre><a name="line98">98</a> </pre></td>
643
          </tr>
644
        
645
          
646
          
647
          <tr class="uncovered">
648
            <td><pre><a name="line99">99</a>     # to avoid having to get the user's email / password, we can get</pre></td>
649
          </tr>
650
        
651
          
652
          
653
          <tr class="uncovered">
654
            <td><pre><a name="line100">100</a>     # their appcfg_cookies file and put it in ~</pre></td>
655
          </tr>
656
        
657
          
658
          
659
          <tr class="uncovered">
660
            <td><pre><a name="line101">101</a>     remote = job_data[&quot;@appcfg_cookies&quot;]</pre></td>
661
          </tr>
662
        
663
          
664
          
665
          <tr class="uncovered">
666
            <td><pre><a name="line102">102</a>     local = File.expand_path(&quot;~&quot;)</pre></td>
667
          </tr>
668
        
669
          
670
          
671
          <tr class="uncovered">
672
            <td><pre><a name="line103">103</a>     Djinn.copy_file_to_dir(remote, local, job_data)</pre></td>
673
          </tr>
674
        
675
          
676
          
677
          <tr class="uncovered">
678
            <td><pre><a name="line104">104</a> </pre></td>
679
          </tr>
680
        
681
          
682
          
683
          <tr class="uncovered">
684
            <td><pre><a name="line105">105</a>     # TODO(cgb) - check for return val here</pre></td>
685
          </tr>
686
        
687
          
688
          
689
          <tr class="uncovered">
690
            <td><pre><a name="line106">106</a>     appcfg = &quot;/root/appscale/AppServer/appcfg.py&quot;</pre></td>
691
          </tr>
692
        
693
          
694
          
695
          <tr class="uncovered">
696
            <td><pre><a name="line107">107</a>     appid = job_data[&quot;@appid&quot;]</pre></td>
697
          </tr>
698
        
699
          
700
          
701
          <tr class="uncovered">
702
            <td><pre><a name="line108">108</a>     Djinn.log_run(&quot;#{appcfg} update #{app_location} -A #{appid}&quot;)</pre></td>
703
          </tr>
704
        
705
          
706
          
707
          <tr class="uncovered">
708
            <td><pre><a name="line109">109</a>   end</pre></td>
709
          </tr>
710
        
711
          
712
          
713
          <tr class="inferred">
714
            <td><pre><a name="line110">110</a> </pre></td>
715
          </tr>
716
        
717
          
718
          
719
          <tr class="inferred">
720
            <td><pre><a name="line111">111</a> </pre></td>
721
          </tr>
722
        
723
          
724
          
725
          <tr class="marked">
726
            <td><pre><a name="line112">112</a>   def get_app_url(job_data)</pre></td>
727
          </tr>
728
        
729
          
730
          
731
          <tr class="uncovered">
732
            <td><pre><a name="line113">113</a>     host = &quot;http://#{job_data['@appid']}.appspot.com&quot;</pre></td>
733
          </tr>
734
        
735
          
736
          
737
          <tr class="uncovered">
738
            <td><pre><a name="line114">114</a>     Djinn.log_debug(&quot;Google App Engine app is hosted at #{host}&quot;)</pre></td>
739
          </tr>
740
        
741
          
742
          
743
          <tr class="uncovered">
744
            <td><pre><a name="line115">115</a>     return host</pre></td>
745
          </tr>
746
        
747
          
748
          
749
          <tr class="uncovered">
750
            <td><pre><a name="line116">116</a>   end</pre></td>
751
          </tr>
752
        
753
          
754
          
755
          <tr class="inferred">
756
            <td><pre><a name="line117">117</a> </pre></td>
757
          </tr>
758
        
759
          
760
          
761
          <tr class="inferred">
762
            <td><pre><a name="line118">118</a> </pre></td>
763
          </tr>
764
        
765
          
766
          
767
          <tr class="marked">
768
            <td><pre><a name="line119">119</a>   def engine_name()</pre></td>
769
          </tr>
770
        
771
          
772
          
773
          <tr class="uncovered">
774
            <td><pre><a name="line120">120</a>     return &quot;Google App Engine&quot;</pre></td>
775
          </tr>
776
        
777
          
778
          
779
          <tr class="uncovered">
780
            <td><pre><a name="line121">121</a>   end</pre></td>
781
          </tr>
782
        
783
          
784
          
785
          <tr class="uncovered">
786
            <td><pre><a name="line122">122</a> end</pre></td>
787
          </tr>
788
        
789
      </tbody>
790
    </table>
791
836 by Chris Bunch
removed eval from set_parameters, added more tests to test out each parameter we send to it, and added documentation on methods that we've tested so far
792
    <p>Generated on Thu Feb 16 23:10:19 -0800 2012 with <a href="http://github.com/relevance/rcov">rcov 0.9.8</a></p>
831 by Chris Bunch
refactored tests to use flexmock, and removed exception writing to ~/.appscale, since we weren't using it anyways and it prevented running tests on non-AppScale machines
793
794
  </body>
795
</html>