bookie_accounting 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. data/.gitignore +19 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE +22 -0
  4. data/README.md +29 -0
  5. data/Rakefile +15 -0
  6. data/bin/bookie-create-tables +52 -0
  7. data/bin/bookie-data +102 -0
  8. data/bin/bookie-send +110 -0
  9. data/bookie_accounting.gemspec +28 -0
  10. data/lib/bookie.rb +11 -0
  11. data/lib/bookie/config.rb +101 -0
  12. data/lib/bookie/database.rb +656 -0
  13. data/lib/bookie/formatter.rb +149 -0
  14. data/lib/bookie/formatters/comma_dump.rb +24 -0
  15. data/lib/bookie/formatters/spreadsheet.rb +45 -0
  16. data/lib/bookie/formatters/stdout.rb +32 -0
  17. data/lib/bookie/sender.rb +108 -0
  18. data/lib/bookie/senders/standalone.rb +37 -0
  19. data/lib/bookie/senders/torque_cluster.rb +166 -0
  20. data/lib/bookie/version.rb +4 -0
  21. data/snapshot/config.json +12 -0
  22. data/snapshot/default.json +11 -0
  23. data/snapshot/pacct +0 -0
  24. data/snapshot/pacct_large +0 -0
  25. data/snapshot/pacct_test_config.json +14 -0
  26. data/snapshot/test_config.json +13 -0
  27. data/snapshot/torque +3 -0
  28. data/snapshot/torque_invalid_lines +5 -0
  29. data/snapshot/torque_invalid_lines_2 +4 -0
  30. data/snapshot/torque_invalid_lines_3 +3 -0
  31. data/snapshot/torque_large +100 -0
  32. data/spec/comma_dump_formatter_spec.rb +56 -0
  33. data/spec/config_spec.rb +55 -0
  34. data/spec/database_spec.rb +625 -0
  35. data/spec/formatter_spec.rb +93 -0
  36. data/spec/sender_spec.rb +104 -0
  37. data/spec/spec_helper.rb +121 -0
  38. data/spec/spreadsheet_formatter_spec.rb +112 -0
  39. data/spec/standalone_sender_spec.rb +40 -0
  40. data/spec/stdout_formatter_spec.rb +66 -0
  41. data/spec/torque_cluster_sender_spec.rb +111 -0
  42. metadata +227 -0
@@ -0,0 +1,4 @@
1
+ module Bookie
2
+ #The library version
3
+ VERSION = "0.0.1"
4
+ end
@@ -0,0 +1,12 @@
1
+ {
2
+ "Database type" : "mysql2",
3
+ "Database" : "bookie",
4
+ "Server" : "localhost",
5
+ "Port" : 8080,
6
+ "Username" : "root",
7
+ "Password" : "test",
8
+ "Hostname" : "localhost",
9
+ "System type" : "torque_cluster",
10
+ "Cores" : 4,
11
+ "Memory" : 8000000
12
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "Database type" : "sqlite3",
3
+ "Server" : "localhost",
4
+ "Database" : "snapshot/bookie_test.sqlite",
5
+ "Username" : "blm768",
6
+ "Password" : "test",
7
+ "System type" : "standalone",
8
+ "Hostname" : "localhost",
9
+ "Cores" : 8,
10
+ "Memory" : 8000000
11
+ }
data/snapshot/pacct ADDED
Binary file
Binary file
@@ -0,0 +1,14 @@
1
+ {
2
+ "Database type" : "sqlite3",
3
+ "Server" : "localhost",
4
+ "Port" : 8080,
5
+ "Database" : "snapshot/bookie_test.sqlite",
6
+ "Username" : "blm768",
7
+ "Password" : "test",
8
+ "Excluded users": ["root"],
9
+ "System type" : "standalone",
10
+ "Hostname" : "localhost",
11
+ "Cores" : 8,
12
+ "Memory" : 8000000,
13
+ "Maximum idle time" : 5
14
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "Database type" : "sqlite3",
3
+ "Server" : "localhost",
4
+ "Port" : 8080,
5
+ "Database" : "test.sqlite",
6
+ "Username" : "blm768",
7
+ "Password" : "test",
8
+ "Excluded users": ["root"],
9
+ "System type" : "torque_cluster",
10
+ "Hostname" : "localhost",
11
+ "Cores" : 8,
12
+ "Memory" : 8000000
13
+ }
data/snapshot/torque ADDED
@@ -0,0 +1,3 @@
1
+ 10/08/2012 00:00:37;S;1026666[24261].github.com;user=blm768 group=test jobname=ABC-24261 queue=tiny ctime=1349631420 qtime=1349631420 etime=1349631420 start=1349679637 owner=blm768@github.com exec_host=n057/6 Resource_List.ncpus=1 Resource_List.neednodes=1 Resource_List.nodect=1 Resource_List.nodes=1 Resource_List.walltime=02:00:00
2
+ 10/08/2012 00:00:39;E;1026666[24252].github.com;user=blm768 group=test jobname=ABC-24252 queue=tiny ctime=1349631420 qtime=1349631420 etime=1349631420 start=1349679573 owner=blm768@github.com exec_host=n032/7 Resource_List.ncpus=1 Resource_List.neednodes=1 Resource_List.nodect=1 Resource_List.nodes=1 Resource_List.walltime=02:00:00 session=2604 end=1349679639 Exit_status=0 resources_used.cput=00:01:03 resources_used.mem=139776kb resources_used.vmem=173444kb resources_used.walltime=00:01:07
3
+
@@ -0,0 +1,5 @@
1
+ invalid line
2
+ 10/08/2012 00:00:37;S;1026666[24261].github.com;user=blm768 group=test jobname=ABC-24261 queue=tiny ctime=1349631420 qtime=1349631420 etime=1349631420 start=1349679637 owner=blm768@github.com exec_host=n057/6 Resource_List.ncpus=1 Resource_List.neednodes=1 Resource_List.nodect=1 Resource_List.nodes=1 Resource_List.walltime=02:00:00
3
+ 10/08/2012 00:00:39;E;1026666[24252].github.com;user=blm768 group=test jobname=ABC-24252 queue=tiny ctime=1349631420 qtime=1349631420 etime=1349631420 start=1349679573 owner=blm768@github.com exec_host=n032/7 Resource_List.ncpus=1 Resource_List.neednodes=1 Resource_List.nodect=1 Resource_List.nodes=1 Resource_List.walltime=02:00:00 session=2604 end=1349679639 Exit_status=0 resources_used.cput=00:01:03 resources_used.mem=139776kb resources_used.vmem=173444kb resources_used.walltime=00:01:07
4
+ another; invalid line
5
+ yet another;E;invalid line
@@ -0,0 +1,4 @@
1
+ 10/08/2012 00:00:37;S;1026666[24261].github.com;user=blm768 group=test jobname=ABC-24261 queue=tiny ctime=1349631420 qtime=1349631420 etime=1349631420 start=1349679637 owner=blm768@github.com exec_host=n057/6 Resource_List.ncpus=1 Resource_List.neednodes=1 Resource_List.nodect=1 Resource_List.nodes=1 Resource_List.walltime=02:00:00
2
+ 10/08/2012 00:00:39;E;1026666[24252].github.com;user=blm768 group=test jobname=ABC-24252 queue=tiny ctime=1349631420 qtime=1349631420 etime=1349631420 start=1349679573 owner=blm768@github.com exec_host=n032/7 Resource_List.ncpus=1 Resource_List.neednodes=1 Resource_List.nodect=1 Resource_List.nodes=1 Resource_List.walltime=02:00:00 session=2604 end=1349679639 Exit_status=0 resources_used.cput=00:01:03 resources_used.mem=139776kb resources_used.vmem=173444kb resources_used.walltime=00:01:07
3
+ another; invalid line
4
+ yet another;E;invalid line
@@ -0,0 +1,3 @@
1
+ 10/08/2012 00:00:37;S;1026666[24261].github.com;user=blm768 group=test jobname=ABC-24261 queue=tiny ctime=1349631420 qtime=1349631420 etime=1349631420 start=1349679637 owner=blm768@github.com exec_host=n057/6 Resource_List.ncpus=1 Resource_List.neednodes=1 Resource_List.nodect=1 Resource_List.nodes=1 Resource_List.walltime=02:00:00
2
+ 10/08/2012 00:00:39;E;1026666[24252].github.com;user=blm768 group=test jobname=ABC-24252 queue=tiny ctime=1349631420 qtime=1349631420 etime=1349631420 start=1349679573 owner=blm768@github.com exec_host=n032/7 Resource_List.ncpus=1 Resource_List.neednodes=1 Resource_List.nodect=1 Resource_List.nodes=1 Resource_List.walltime=02:00:00 session=2604 end=1349679639 Exit_status=0 resources_used.cput=00:01:03 resources_used.mem=139776kb resources_used.vmem=173444kb resources_used.walltime=00:01:07
3
+ yet another;E;invalid line
@@ -0,0 +1,100 @@
1
+ ;E;1[0].test3;jobname=1 user=abc2 group=group2 start=1325404806 resources_used.walltime=00:00:14 resources_used.cput=00:00:4 resources_used.mem=1014kb resources_used.vmem=0kb Exit_status=1
2
+ ;E;2[0].test3;jobname=2 user=abc2 group=group2 start=1325404828 resources_used.walltime=00:00:12 resources_used.cput=00:00:2 resources_used.mem=873kb resources_used.vmem=0kb Exit_status=1
3
+ ;E;3[0].test3;jobname=3 user=abc1 group=group2 start=1325404856 resources_used.walltime=00:00:4 resources_used.cput=00:00:8 resources_used.mem=853kb resources_used.vmem=0kb Exit_status=0
4
+ ;E;4[0].test3;jobname=4 user=abc2 group=group2 start=1325404872 resources_used.walltime=00:00:8 resources_used.cput=00:00:6 resources_used.mem=862kb resources_used.vmem=0kb Exit_status=0
5
+ ;E;5[0].test1;jobname=5 user=abc1 group=group2 start=1325404888 resources_used.walltime=00:00:12 resources_used.cput=00:00:6 resources_used.mem=1036kb resources_used.vmem=0kb Exit_status=1
6
+ ;E;6[0].test1;jobname=6 user=abc2 group=group1 start=1325404913 resources_used.walltime=00:00:7 resources_used.cput=00:00:3 resources_used.mem=805kb resources_used.vmem=0kb Exit_status=0
7
+ ;E;7[0].test2;jobname=7 user=abc2 group=group1 start=1325404922 resources_used.walltime=00:00:18 resources_used.cput=00:00:1 resources_used.mem=871kb resources_used.vmem=0kb Exit_status=0
8
+ ;E;8[0].test2;jobname=8 user=abc2 group=group3 start=1325404956 resources_used.walltime=00:00:4 resources_used.cput=00:00:5 resources_used.mem=885kb resources_used.vmem=0kb Exit_status=1
9
+ ;E;9[0].test1;jobname=9 user=abc2 group=group1 start=1325404963 resources_used.walltime=00:00:17 resources_used.cput=00:00:0 resources_used.mem=862kb resources_used.vmem=0kb Exit_status=1
10
+ ;E;10[0].test2;jobname=10 user=abc1 group=group2 start=1325404984 resources_used.walltime=00:00:16 resources_used.cput=00:00:0 resources_used.mem=953kb resources_used.vmem=0kb Exit_status=1
11
+ ;E;11[0].test2;jobname=11 user=abc3 group=group2 start=1325405002 resources_used.walltime=00:00:18 resources_used.cput=00:00:9 resources_used.mem=910kb resources_used.vmem=0kb Exit_status=0
12
+ ;E;12[0].test3;jobname=12 user=abc3 group=group2 start=1325405027 resources_used.walltime=00:00:13 resources_used.cput=00:00:8 resources_used.mem=970kb resources_used.vmem=0kb Exit_status=0
13
+ ;E;13[0].test1;jobname=13 user=abc1 group=group3 start=1325405046 resources_used.walltime=00:00:14 resources_used.cput=00:00:7 resources_used.mem=1033kb resources_used.vmem=0kb Exit_status=0
14
+ ;E;14[0].test2;jobname=14 user=abc2 group=group2 start=1325405071 resources_used.walltime=00:00:9 resources_used.cput=00:00:3 resources_used.mem=1018kb resources_used.vmem=0kb Exit_status=1
15
+ ;E;15[0].test1;jobname=15 user=abc3 group=group1 start=1325405094 resources_used.walltime=00:00:6 resources_used.cput=00:00:7 resources_used.mem=807kb resources_used.vmem=0kb Exit_status=1
16
+ ;E;16[0].test3;jobname=16 user=abc2 group=group2 start=1325405116 resources_used.walltime=00:00:4 resources_used.cput=00:00:5 resources_used.mem=978kb resources_used.vmem=0kb Exit_status=0
17
+ ;E;17[0].test3;jobname=17 user=abc3 group=group2 start=1325405138 resources_used.walltime=00:00:2 resources_used.cput=00:00:0 resources_used.mem=952kb resources_used.vmem=0kb Exit_status=0
18
+ ;E;18[0].test2;jobname=18 user=abc3 group=group3 start=1325405148 resources_used.walltime=00:00:12 resources_used.cput=00:00:3 resources_used.mem=928kb resources_used.vmem=0kb Exit_status=0
19
+ ;E;19[0].test3;jobname=19 user=abc2 group=group1 start=1325405172 resources_used.walltime=00:00:8 resources_used.cput=00:00:9 resources_used.mem=1036kb resources_used.vmem=0kb Exit_status=1
20
+ ;E;20[0].test1;jobname=20 user=abc1 group=group3 start=1325405200 resources_used.walltime=00:00:0 resources_used.cput=00:00:0 resources_used.mem=826kb resources_used.vmem=0kb Exit_status=1
21
+ ;E;21[0].test2;jobname=21 user=abc2 group=group3 start=1325405213 resources_used.walltime=00:00:7 resources_used.cput=00:00:2 resources_used.mem=1032kb resources_used.vmem=0kb Exit_status=1
22
+ ;E;22[0].test3;jobname=22 user=abc1 group=group3 start=1325405223 resources_used.walltime=00:00:17 resources_used.cput=00:00:2 resources_used.mem=828kb resources_used.vmem=0kb Exit_status=0
23
+ ;E;23[0].test1;jobname=23 user=abc3 group=group2 start=1325405251 resources_used.walltime=00:00:9 resources_used.cput=00:00:6 resources_used.mem=944kb resources_used.vmem=0kb Exit_status=0
24
+ ;E;24[0].test3;jobname=24 user=abc3 group=group3 start=1325405279 resources_used.walltime=00:00:1 resources_used.cput=00:00:0 resources_used.mem=880kb resources_used.vmem=0kb Exit_status=1
25
+ ;E;25[0].test2;jobname=25 user=abc2 group=group2 start=1325405296 resources_used.walltime=00:00:4 resources_used.cput=00:00:4 resources_used.mem=828kb resources_used.vmem=0kb Exit_status=0
26
+ ;E;26[0].test3;jobname=26 user=abc2 group=group1 start=1325405303 resources_used.walltime=00:00:17 resources_used.cput=00:00:6 resources_used.mem=984kb resources_used.vmem=0kb Exit_status=0
27
+ ;E;27[0].test3;jobname=27 user=abc1 group=group3 start=1325405322 resources_used.walltime=00:00:18 resources_used.cput=00:00:9 resources_used.mem=800kb resources_used.vmem=0kb Exit_status=0
28
+ ;E;28[0].test2;jobname=28 user=abc2 group=group3 start=1325405357 resources_used.walltime=00:00:3 resources_used.cput=00:00:7 resources_used.mem=819kb resources_used.vmem=0kb Exit_status=0
29
+ ;E;29[0].test1;jobname=29 user=abc1 group=group2 start=1325405366 resources_used.walltime=00:00:14 resources_used.cput=00:00:1 resources_used.mem=883kb resources_used.vmem=0kb Exit_status=0
30
+ ;E;30[0].test2;jobname=30 user=abc3 group=group2 start=1325405399 resources_used.walltime=00:00:1 resources_used.cput=00:00:8 resources_used.mem=891kb resources_used.vmem=0kb Exit_status=1
31
+ ;E;31[0].test1;jobname=31 user=abc1 group=group3 start=1325405402 resources_used.walltime=00:00:18 resources_used.cput=00:00:4 resources_used.mem=1039kb resources_used.vmem=0kb Exit_status=1
32
+ ;E;32[0].test2;jobname=32 user=abc2 group=group3 start=1325405428 resources_used.walltime=00:00:12 resources_used.cput=00:00:2 resources_used.mem=855kb resources_used.vmem=0kb Exit_status=0
33
+ ;E;33[0].test2;jobname=33 user=abc3 group=group1 start=1325405442 resources_used.walltime=00:00:18 resources_used.cput=00:00:5 resources_used.mem=820kb resources_used.vmem=0kb Exit_status=1
34
+ ;E;34[0].test1;jobname=34 user=abc1 group=group2 start=1325405465 resources_used.walltime=00:00:15 resources_used.cput=00:00:4 resources_used.mem=838kb resources_used.vmem=0kb Exit_status=1
35
+ ;E;35[0].test3;jobname=35 user=abc2 group=group2 start=1325405494 resources_used.walltime=00:00:6 resources_used.cput=00:00:7 resources_used.mem=887kb resources_used.vmem=0kb Exit_status=0
36
+ ;E;36[0].test1;jobname=36 user=abc3 group=group2 start=1325405508 resources_used.walltime=00:00:12 resources_used.cput=00:00:2 resources_used.mem=841kb resources_used.vmem=0kb Exit_status=0
37
+ ;E;37[0].test1;jobname=37 user=abc2 group=group3 start=1325405539 resources_used.walltime=00:00:1 resources_used.cput=00:00:5 resources_used.mem=861kb resources_used.vmem=0kb Exit_status=0
38
+ ;E;38[0].test1;jobname=38 user=abc3 group=group2 start=1325405553 resources_used.walltime=00:00:7 resources_used.cput=00:00:1 resources_used.mem=886kb resources_used.vmem=0kb Exit_status=0
39
+ ;E;39[0].test3;jobname=39 user=abc3 group=group3 start=1325405563 resources_used.walltime=00:00:17 resources_used.cput=00:00:5 resources_used.mem=987kb resources_used.vmem=0kb Exit_status=0
40
+ ;E;40[0].test2;jobname=40 user=abc1 group=group3 start=1325405582 resources_used.walltime=00:00:18 resources_used.cput=00:00:1 resources_used.mem=954kb resources_used.vmem=0kb Exit_status=0
41
+ ;E;41[0].test1;jobname=41 user=abc1 group=group2 start=1325405603 resources_used.walltime=00:00:17 resources_used.cput=00:00:5 resources_used.mem=1015kb resources_used.vmem=0kb Exit_status=0
42
+ ;E;42[0].test2;jobname=42 user=abc1 group=group3 start=1325405631 resources_used.walltime=00:00:9 resources_used.cput=00:00:0 resources_used.mem=802kb resources_used.vmem=0kb Exit_status=1
43
+ ;E;43[0].test2;jobname=43 user=abc1 group=group1 start=1325405648 resources_used.walltime=00:00:12 resources_used.cput=00:00:0 resources_used.mem=1026kb resources_used.vmem=0kb Exit_status=0
44
+ ;E;44[0].test2;jobname=44 user=abc1 group=group1 start=1325405672 resources_used.walltime=00:00:8 resources_used.cput=00:00:3 resources_used.mem=957kb resources_used.vmem=0kb Exit_status=0
45
+ ;E;45[0].test1;jobname=45 user=abc3 group=group1 start=1325405695 resources_used.walltime=00:00:5 resources_used.cput=00:00:0 resources_used.mem=1017kb resources_used.vmem=0kb Exit_status=1
46
+ ;E;46[0].test2;jobname=46 user=abc1 group=group3 start=1325405711 resources_used.walltime=00:00:9 resources_used.cput=00:00:3 resources_used.mem=881kb resources_used.vmem=0kb Exit_status=0
47
+ ;E;47[0].test1;jobname=47 user=abc2 group=group1 start=1325405722 resources_used.walltime=00:00:18 resources_used.cput=00:00:5 resources_used.mem=840kb resources_used.vmem=0kb Exit_status=0
48
+ ;E;48[0].test3;jobname=48 user=abc2 group=group2 start=1325405747 resources_used.walltime=00:00:13 resources_used.cput=00:00:5 resources_used.mem=982kb resources_used.vmem=0kb Exit_status=1
49
+ ;E;49[0].test2;jobname=49 user=abc2 group=group3 start=1325405777 resources_used.walltime=00:00:3 resources_used.cput=00:00:4 resources_used.mem=866kb resources_used.vmem=0kb Exit_status=0
50
+ ;E;50[0].test1;jobname=50 user=abc2 group=group3 start=1325405788 resources_used.walltime=00:00:12 resources_used.cput=00:00:1 resources_used.mem=1025kb resources_used.vmem=0kb Exit_status=0
51
+ ;E;51[0].test2;jobname=51 user=abc2 group=group3 start=1325405805 resources_used.walltime=00:00:15 resources_used.cput=00:00:3 resources_used.mem=954kb resources_used.vmem=0kb Exit_status=0
52
+ ;E;52[0].test1;jobname=52 user=abc1 group=group1 start=1325405836 resources_used.walltime=00:00:4 resources_used.cput=00:00:2 resources_used.mem=943kb resources_used.vmem=0kb Exit_status=1
53
+ ;E;53[0].test1;jobname=53 user=abc2 group=group2 start=1325405843 resources_used.walltime=00:00:17 resources_used.cput=00:00:8 resources_used.mem=1002kb resources_used.vmem=0kb Exit_status=0
54
+ ;E;54[0].test2;jobname=54 user=abc2 group=group3 start=1325405876 resources_used.walltime=00:00:4 resources_used.cput=00:00:8 resources_used.mem=1002kb resources_used.vmem=0kb Exit_status=1
55
+ ;E;55[0].test2;jobname=55 user=abc1 group=group2 start=1325405887 resources_used.walltime=00:00:13 resources_used.cput=00:00:8 resources_used.mem=976kb resources_used.vmem=0kb Exit_status=0
56
+ ;E;56[0].test2;jobname=56 user=abc2 group=group1 start=1325405918 resources_used.walltime=00:00:2 resources_used.cput=00:00:5 resources_used.mem=1036kb resources_used.vmem=0kb Exit_status=1
57
+ ;E;57[0].test1;jobname=57 user=abc3 group=group3 start=1325405930 resources_used.walltime=00:00:10 resources_used.cput=00:00:3 resources_used.mem=916kb resources_used.vmem=0kb Exit_status=0
58
+ ;E;58[0].test1;jobname=58 user=abc3 group=group2 start=1325405953 resources_used.walltime=00:00:7 resources_used.cput=00:00:0 resources_used.mem=1013kb resources_used.vmem=0kb Exit_status=0
59
+ ;E;59[0].test3;jobname=59 user=abc2 group=group1 start=1325405979 resources_used.walltime=00:00:1 resources_used.cput=00:00:5 resources_used.mem=1033kb resources_used.vmem=0kb Exit_status=0
60
+ ;E;60[0].test3;jobname=60 user=abc1 group=group3 start=1325405999 resources_used.walltime=00:00:1 resources_used.cput=00:00:1 resources_used.mem=831kb resources_used.vmem=0kb Exit_status=0
61
+ ;E;61[0].test2;jobname=61 user=abc2 group=group1 start=1325406013 resources_used.walltime=00:00:7 resources_used.cput=00:00:6 resources_used.mem=986kb resources_used.vmem=0kb Exit_status=0
62
+ ;E;62[0].test1;jobname=62 user=abc3 group=group2 start=1325406022 resources_used.walltime=00:00:18 resources_used.cput=00:00:9 resources_used.mem=895kb resources_used.vmem=0kb Exit_status=1
63
+ ;E;63[0].test1;jobname=63 user=abc2 group=group2 start=1325406051 resources_used.walltime=00:00:9 resources_used.cput=00:00:4 resources_used.mem=903kb resources_used.vmem=0kb Exit_status=0
64
+ ;E;64[0].test1;jobname=64 user=abc1 group=group2 start=1325406077 resources_used.walltime=00:00:3 resources_used.cput=00:00:7 resources_used.mem=995kb resources_used.vmem=0kb Exit_status=1
65
+ ;E;65[0].test1;jobname=65 user=abc1 group=group1 start=1325406098 resources_used.walltime=00:00:2 resources_used.cput=00:00:8 resources_used.mem=961kb resources_used.vmem=0kb Exit_status=0
66
+ ;E;66[0].test2;jobname=66 user=abc2 group=group1 start=1325406102 resources_used.walltime=00:00:18 resources_used.cput=00:00:8 resources_used.mem=1021kb resources_used.vmem=0kb Exit_status=1
67
+ ;E;67[0].test3;jobname=67 user=abc3 group=group3 start=1325406140 resources_used.walltime=00:00:0 resources_used.cput=00:00:3 resources_used.mem=874kb resources_used.vmem=0kb Exit_status=0
68
+ ;E;68[0].test2;jobname=68 user=abc1 group=group1 start=1325406141 resources_used.walltime=00:00:19 resources_used.cput=00:00:3 resources_used.mem=851kb resources_used.vmem=0kb Exit_status=0
69
+ ;E;69[0].test1;jobname=69 user=abc2 group=group1 start=1325406177 resources_used.walltime=00:00:3 resources_used.cput=00:00:5 resources_used.mem=922kb resources_used.vmem=0kb Exit_status=0
70
+ ;E;70[0].test2;jobname=70 user=abc2 group=group2 start=1325406195 resources_used.walltime=00:00:5 resources_used.cput=00:00:4 resources_used.mem=961kb resources_used.vmem=0kb Exit_status=1
71
+ ;E;71[0].test3;jobname=71 user=abc3 group=group1 start=1325406213 resources_used.walltime=00:00:7 resources_used.cput=00:00:3 resources_used.mem=863kb resources_used.vmem=0kb Exit_status=0
72
+ ;E;72[0].test1;jobname=72 user=abc2 group=group2 start=1325406234 resources_used.walltime=00:00:6 resources_used.cput=00:00:7 resources_used.mem=954kb resources_used.vmem=0kb Exit_status=0
73
+ ;E;73[0].test2;jobname=73 user=abc2 group=group1 start=1325406257 resources_used.walltime=00:00:3 resources_used.cput=00:00:6 resources_used.mem=911kb resources_used.vmem=0kb Exit_status=0
74
+ ;E;74[0].test2;jobname=74 user=abc1 group=group2 start=1325406265 resources_used.walltime=00:00:15 resources_used.cput=00:00:9 resources_used.mem=1036kb resources_used.vmem=0kb Exit_status=0
75
+ ;E;75[0].test1;jobname=75 user=abc3 group=group3 start=1325406298 resources_used.walltime=00:00:2 resources_used.cput=00:00:3 resources_used.mem=941kb resources_used.vmem=0kb Exit_status=1
76
+ ;E;76[0].test3;jobname=76 user=abc3 group=group3 start=1325406310 resources_used.walltime=00:00:10 resources_used.cput=00:00:1 resources_used.mem=937kb resources_used.vmem=0kb Exit_status=1
77
+ ;E;77[0].test2;jobname=77 user=abc3 group=group1 start=1325406336 resources_used.walltime=00:00:4 resources_used.cput=00:00:2 resources_used.mem=942kb resources_used.vmem=0kb Exit_status=0
78
+ ;E;78[0].test3;jobname=78 user=abc2 group=group3 start=1325406352 resources_used.walltime=00:00:8 resources_used.cput=00:00:8 resources_used.mem=904kb resources_used.vmem=0kb Exit_status=0
79
+ ;E;79[0].test2;jobname=79 user=abc2 group=group2 start=1325406361 resources_used.walltime=00:00:19 resources_used.cput=00:00:1 resources_used.mem=840kb resources_used.vmem=0kb Exit_status=0
80
+ ;E;80[0].test1;jobname=80 user=abc1 group=group3 start=1325406395 resources_used.walltime=00:00:5 resources_used.cput=00:00:4 resources_used.mem=863kb resources_used.vmem=0kb Exit_status=1
81
+ ;E;81[0].test1;jobname=81 user=abc1 group=group2 start=1325406410 resources_used.walltime=00:00:10 resources_used.cput=00:00:4 resources_used.mem=973kb resources_used.vmem=0kb Exit_status=0
82
+ ;E;82[0].test3;jobname=82 user=abc1 group=group2 start=1325406433 resources_used.walltime=00:00:7 resources_used.cput=00:00:3 resources_used.mem=984kb resources_used.vmem=0kb Exit_status=1
83
+ ;E;83[0].test2;jobname=83 user=abc3 group=group2 start=1325406444 resources_used.walltime=00:00:16 resources_used.cput=00:00:6 resources_used.mem=985kb resources_used.vmem=0kb Exit_status=0
84
+ ;E;84[0].test1;jobname=84 user=abc1 group=group2 start=1325406477 resources_used.walltime=00:00:3 resources_used.cput=00:00:0 resources_used.mem=839kb resources_used.vmem=0kb Exit_status=0
85
+ ;E;85[0].test2;jobname=85 user=abc1 group=group3 start=1325406492 resources_used.walltime=00:00:8 resources_used.cput=00:00:3 resources_used.mem=1042kb resources_used.vmem=0kb Exit_status=1
86
+ ;E;86[0].test1;jobname=86 user=abc1 group=group1 start=1325406511 resources_used.walltime=00:00:9 resources_used.cput=00:00:4 resources_used.mem=1011kb resources_used.vmem=0kb Exit_status=1
87
+ ;E;87[0].test3;jobname=87 user=abc1 group=group3 start=1325406528 resources_used.walltime=00:00:12 resources_used.cput=00:00:2 resources_used.mem=819kb resources_used.vmem=0kb Exit_status=0
88
+ ;E;88[0].test3;jobname=88 user=abc2 group=group3 start=1325406546 resources_used.walltime=00:00:14 resources_used.cput=00:00:7 resources_used.mem=1004kb resources_used.vmem=0kb Exit_status=1
89
+ ;E;89[0].test3;jobname=89 user=abc3 group=group3 start=1325406577 resources_used.walltime=00:00:3 resources_used.cput=00:00:1 resources_used.mem=882kb resources_used.vmem=0kb Exit_status=1
90
+ ;E;90[0].test2;jobname=90 user=abc1 group=group3 start=1325406582 resources_used.walltime=00:00:18 resources_used.cput=00:00:9 resources_used.mem=881kb resources_used.vmem=0kb Exit_status=0
91
+ ;E;91[0].test1;jobname=91 user=abc3 group=group2 start=1325406607 resources_used.walltime=00:00:13 resources_used.cput=00:00:0 resources_used.mem=905kb resources_used.vmem=0kb Exit_status=0
92
+ ;E;92[0].test1;jobname=92 user=abc3 group=group3 start=1325406630 resources_used.walltime=00:00:10 resources_used.cput=00:00:4 resources_used.mem=877kb resources_used.vmem=0kb Exit_status=0
93
+ ;E;93[0].test2;jobname=93 user=abc2 group=group1 start=1325406648 resources_used.walltime=00:00:12 resources_used.cput=00:00:8 resources_used.mem=978kb resources_used.vmem=0kb Exit_status=1
94
+ ;E;94[0].test1;jobname=94 user=abc1 group=group1 start=1325406665 resources_used.walltime=00:00:15 resources_used.cput=00:00:2 resources_used.mem=902kb resources_used.vmem=0kb Exit_status=1
95
+ ;E;95[0].test3;jobname=95 user=abc2 group=group1 start=1325406687 resources_used.walltime=00:00:13 resources_used.cput=00:00:8 resources_used.mem=994kb resources_used.vmem=0kb Exit_status=0
96
+ ;E;96[0].test2;jobname=96 user=abc1 group=group1 start=1325406710 resources_used.walltime=00:00:10 resources_used.cput=00:00:5 resources_used.mem=925kb resources_used.vmem=0kb Exit_status=0
97
+ ;E;97[0].test1;jobname=97 user=abc1 group=group3 start=1325406728 resources_used.walltime=00:00:12 resources_used.cput=00:00:3 resources_used.mem=807kb resources_used.vmem=0kb Exit_status=1
98
+ ;E;98[0].test3;jobname=98 user=abc1 group=group1 start=1325406755 resources_used.walltime=00:00:5 resources_used.cput=00:00:2 resources_used.mem=1011kb resources_used.vmem=0kb Exit_status=0
99
+ ;E;99[0].test3;jobname=99 user=abc1 group=group1 start=1325406780 resources_used.walltime=00:00:0 resources_used.cput=00:00:9 resources_used.mem=915kb resources_used.vmem=0kb Exit_status=1
100
+ ;E;100[0].test1;jobname=100 user=abc2 group=group3 start=1325406790 resources_used.walltime=00:00:10 resources_used.cput=00:00:2 resources_used.mem=924kb resources_used.vmem=0kb Exit_status=1
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ module Bookie
4
+ module Formatters
5
+ module CommaDump
6
+
7
+ end
8
+ end
9
+ end
10
+
11
+ describe Bookie::Formatters::CommaDump do
12
+ before(:all) do
13
+ Bookie::Database::Migration.up
14
+ Helpers::generate_database
15
+ @jobs = Bookie::Database::Job
16
+ end
17
+
18
+ before(:each) do
19
+ @m = IOMock.new
20
+ File.expects(:open).returns(@m)
21
+ @formatter = Bookie::Formatter.new(:comma_dump, 'test.csv')
22
+ end
23
+
24
+ after(:all) do
25
+ FileUtils.rm('test.sqlite')
26
+ end
27
+
28
+ it "correctly opens files" do
29
+ File.expects(:open).with('test.csv')
30
+ f = Bookie::Formatter::new(:comma_dump, 'test.csv')
31
+ end
32
+
33
+ it "correctly formats jobs" do
34
+ @formatter.print_jobs(@jobs.order(:start_time).limit(2))
35
+ @m.buf.should eql <<-eos
36
+ User, Group, System, System type, Start time, End time, Wall time, CPU time, Memory usage, Exit code
37
+ root, root, test1, Standalone, 2012-01-01 00:00:00, 2012-01-01 01:00:00, 01:00:00, 00:01:40, 200kb (avg), 0
38
+ test, default, test1, Standalone, 2012-01-01 01:00:00, 2012-01-01 02:00:00, 01:00:00, 00:01:40, 200kb (avg), 1
39
+ eos
40
+ end
41
+
42
+ it "correctly formats summaries" do
43
+ Time.expects(:now).returns(Time.local(2012) + 36000 * 4).at_least_once
44
+ @formatter.print_summary(@jobs.order(:start_time).limit(5), Bookie::Database::System)
45
+ @m.buf.should eql <<-eos
46
+ Number of jobs, 5
47
+ Total wall time, 05:00:00
48
+ Total CPU time, 00:08:20
49
+ Successful, 60.0000%
50
+ Available CPU time, 140:00:00
51
+ CPU time used, 0.0992%
52
+ Available memory (average), 1750000 kb
53
+ Memory used (average), 0.0014%
54
+ eos
55
+ end
56
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ require 'active_record'
4
+
5
+ describe Bookie::Config do
6
+ it "loads correct data" do
7
+ config = Bookie::Config.new('snapshot/test_config.json')
8
+
9
+ config.db_type.should eql "sqlite3"
10
+ config.server.should eql "localhost"
11
+ config.port.should eql 8080
12
+ config.database.should eql "test.sqlite"
13
+ config.username.should eql "blm768"
14
+ config.password.should eql "test"
15
+ config.excluded_users.should eql Set.new(["root"])
16
+ config.hostname.should eql "localhost"
17
+ config.cores.should eql 8
18
+ config.memory.should eql 8000000
19
+ config.system_type.should eql 'torque_cluster'
20
+ end
21
+
22
+ it "correctly verifies types" do
23
+ config = Bookie::Config.new('snapshot/default.json')
24
+ config.verify_type("abc", "test", String)
25
+ expect { config.verify_type("abc", "test", Fixnum) }.to raise_error(TypeError, 'Invalid data type String for JSON field "test": Fixnum expected')
26
+ end
27
+
28
+ it "sets correct defaults" do
29
+ dconfig = Bookie::Config.new('snapshot/default.json')
30
+
31
+ dconfig.port.should eql nil
32
+ dconfig.excluded_users.should eql Set.new([])
33
+ end
34
+
35
+ it 'correctly handles missing fields' do
36
+ fields = JSON.parse(File.read('snapshot/default.json'))
37
+ fields.keys.each do |key|
38
+ removed = fields.delete(key)
39
+ JSON.stubs(:parse).returns(fields)
40
+ expect { Bookie::Config.new('snapshot/default.json') }.to raise_error(/^Field "[\w ]+" must have a non-null value.$/)
41
+ fields[key] = removed
42
+ end
43
+ JSON.stubs(:parse).returns(fields)
44
+ #This should not raise an error.
45
+ Bookie::Config.new('snapshot/default.json')
46
+ end
47
+
48
+ it "configures and connects to the database" do
49
+ config = Bookie::Config.new('snapshot/test_config.json')
50
+ ActiveRecord::Base.expects(:establish_connection)
51
+ config.connect
52
+ ActiveRecord::Base.time_zone_aware_attributes.should eql true
53
+ ActiveRecord::Base.default_timezone.should eql :utc
54
+ end
55
+ end
@@ -0,0 +1,625 @@
1
+ require 'spec_helper'
2
+
3
+ module Helpers
4
+ def self.create_summaries(obj, base_time)
5
+ start_time_1 = base_time
6
+ end_time_1 = base_time + 3600 * 40
7
+ start_time_2 = base_time + 1800
8
+ end_time_2 = base_time + (36000 * 2 + 18000)
9
+ {
10
+ :all => obj.summary,
11
+ :all_constrained => obj.summary(start_time_1, end_time_1),
12
+ :clipped => obj.summary(start_time_2, end_time_2),
13
+ :empty => obj.summary(Time.at(0), Time.at(0)),
14
+ }
15
+ end
16
+
17
+ def test_relations(job, relations)
18
+ rels = [job.user, job.user.group, job.system, job.system.system_type]
19
+ rels.each do |r|
20
+ if relations.include?(r)
21
+ old_r = relations[r]
22
+ old_r.should eql r
23
+ end
24
+ relations[r] = r
25
+ end
26
+ end
27
+ end
28
+
29
+ describe Bookie::Database do
30
+ before(:all) do
31
+ unless @generated
32
+ Bookie::Database::Migration.up
33
+ Helpers::generate_database
34
+ @generated = true
35
+ end
36
+ end
37
+
38
+ after(:all) do
39
+ Bookie::Database::Migration.down
40
+ end
41
+
42
+ describe Bookie::Database::Lock do
43
+ it "finds locks" do
44
+ Lock = Bookie::Database::Lock
45
+ Lock[:users].should_not eql nil
46
+ Lock[:users].name.should eql 'users'
47
+ Lock[:groups].should_not eql nil
48
+ Lock[:groups].name.should eql 'groups'
49
+ expect { Lock[:dummy] }.to raise_error("Unable to find lock 'dummy'")
50
+ end
51
+
52
+ it "locks records (will probably fail if the testing DB doesn't support row locks)" #do
53
+ #lock = Bookie::Database::Lock[:users]
54
+ #thread = nil
55
+ #lock.synchronize do
56
+ # thread = Thread.new {
57
+ # t = Time.now
58
+ # ActiveRecord::Base.connection_pool.with_connection do
59
+ # lock.synchronize do
60
+ # Bookie::Database::User.first
61
+ # end
62
+ # end
63
+ # (Time.now - t).should >= 0.5
64
+ # }
65
+ # sleep(1)
66
+ #end
67
+ #thread.join
68
+ #end
69
+
70
+ it "validates fields" do
71
+ lock = Bookie::Database::Lock.new
72
+ lock.name = nil
73
+ lock.valid?.should eql false
74
+ lock.name = ''
75
+ lock.valid?.should eql false
76
+ lock.name = 'test'
77
+ lock.valid?.should eql true
78
+ end
79
+ end
80
+
81
+ describe Bookie::Database::Job do
82
+ before(:each) do
83
+ @jobs = Bookie::Database::Job
84
+ @base_time = @jobs.first.start_time
85
+ end
86
+
87
+ it "correctly sets end times" do
88
+ @jobs.find_each do |job|
89
+ job.end_time.should eql job.start_time + job.wall_time
90
+ job.end_time.should eql job.read_attribute(:end_time)
91
+ end
92
+ #Test the update hook.
93
+ job = Bookie::Database::Job.first
94
+ job.start_time = job.start_time - 1
95
+ job.save!
96
+ job.end_time.should eql job.read_attribute(:end_time)
97
+ job.start_time = job.start_time + 1
98
+ job.save!
99
+ end
100
+
101
+ it "correctly filters by user" do
102
+ jobs = @jobs.by_user_name('root').all
103
+ jobs.length.should eql 10
104
+ jobs[0].user.name.should eql "root"
105
+ jobs = @jobs.by_user_name('test').order(:end_time).all
106
+ jobs.length.should eql 20
107
+ jobs.each do |job|
108
+ job.user.name.should eql 'test'
109
+ end
110
+ jobs[0].user_id.should_not eql jobs[-1].user_id
111
+ jobs = @jobs.by_user_name('user').all
112
+ jobs.length.should eql 0
113
+ end
114
+
115
+ it "correctly filters by group" do
116
+ jobs = @jobs.by_group_name("root").all
117
+ jobs.length.should eql 10
118
+ jobs.each do |job|
119
+ job.user.group.name.should eql "root"
120
+ end
121
+ jobs = @jobs.by_group_name("admin").order(:start_time).all
122
+ jobs.length.should eql 20
123
+ jobs[0].user.name.should_not eql jobs[1].user.name
124
+ jobs = @jobs.by_group_name("test").all
125
+ jobs.length.should eql 0
126
+ end
127
+
128
+ it "correctly filters by system" do
129
+ jobs = @jobs.by_system_name('test1')
130
+ jobs.length.should eql 20
131
+ jobs = @jobs.by_system_name('test2')
132
+ jobs.length.should eql 10
133
+ jobs = @jobs.by_system_name('test3')
134
+ jobs.length.should eql 10
135
+ jobs = @jobs.by_system_name('test4')
136
+ jobs.length.should eql 0
137
+ end
138
+
139
+ it "correctly filters by system type" do
140
+ sys_type = Bookie::Database::SystemType.find_by_name('Standalone')
141
+ jobs = @jobs.by_system_type(sys_type)
142
+ jobs.length.should eql 20
143
+ sys_type = Bookie::Database::SystemType.find_by_name('TORQUE cluster')
144
+ jobs = @jobs.by_system_type(sys_type)
145
+ jobs.length.should eql 20
146
+ end
147
+
148
+ it "correctly filters by command name" do
149
+ jobs = @jobs.by_command_name('vi')
150
+ jobs.length.should eql 20
151
+ jobs = @jobs.by_command_name('emacs')
152
+ jobs.length.should eql 20
153
+ end
154
+
155
+ it "correctly filters by start time" do
156
+ jobs = @jobs.by_start_time_range(@base_time, @base_time + 3600 * 2 + 1)
157
+ jobs.length.should eql 3
158
+ jobs = @jobs.by_start_time_range(@base_time + 1, @base_time + 3600 * 2)
159
+ jobs.length.should eql 1
160
+ jobs = @jobs.by_start_time_range(Time.at(0), Time.at(3))
161
+ jobs.length.should eql 0
162
+ end
163
+
164
+ it "correctly filters by end time" do
165
+ jobs = @jobs.by_end_time_range(@base_time, @base_time + 3600 * 2 + 1)
166
+ jobs.length.should eql 2
167
+ jobs = @jobs.by_end_time_range(@base_time + 1, @base_time + 3600 * 2)
168
+ jobs.length.should eql 1
169
+ jobs = @jobs.by_end_time_range(Time.at(0), Time.at(3))
170
+ jobs.length.should eql 0
171
+ end
172
+
173
+ it "correctly filters by inclusive time range" do
174
+ jobs = @jobs.by_time_range_inclusive(@base_time, @base_time + 3600 * 2 + 1)
175
+ jobs.length.should eql 3
176
+ jobs = @jobs.by_time_range_inclusive(@base_time + 1, @base_time + 3600 * 2 - 1)
177
+ jobs.length.should eql 2
178
+ jobs = @jobs.by_time_range_inclusive(Time.at(0), Time.at(3))
179
+ jobs.length.should eql 0
180
+ expect {
181
+ @jobs.by_time_range_inclusive(Time.local(2012), Time.local(2012) - 1)
182
+ }.to raise_error('Max time must be greater than or equal to min time')
183
+ end
184
+
185
+ it "correctly chains filters" do
186
+ jobs = @jobs.by_user_name("test")
187
+ jobs = jobs.by_start_time_range(@base_time + 3600, @base_time + 3601)
188
+ jobs.length.should eql 1
189
+ jobs[0].user.group.name.should eql "default"
190
+ end
191
+
192
+ describe "::all_with_relations" do
193
+ it "loads all relations" do
194
+ jobs = Bookie::Database::Job.limit(5)
195
+ relations = {}
196
+ jobs.all_with_relations.each do |job|
197
+ test_relations(job, relations)
198
+ end
199
+ end
200
+ end
201
+
202
+ describe "::summary" do
203
+ before(:all) do
204
+ Time.expects(:now).returns(Time.local(2012) + 36000 * 4).at_least_once
205
+ @base_time = Time.local(2012)
206
+ @jobs = Bookie::Database::Job
207
+ @length = @jobs.all.length
208
+ @summary = Helpers::create_summaries(@jobs, Time.local(2012))
209
+ end
210
+
211
+ it "produces correct summary totals" do
212
+ @summary[:all][:jobs].length.should eql @length
213
+ @summary[:all][:wall_time].should eql @length * 3600
214
+ @summary[:all][:cpu_time].should eql @length * 100
215
+ @summary[:all][:memory_time].should eql @length * 200 * 3600
216
+ @summary[:all][:successful].should eql 0.5
217
+ @summary[:all_constrained][:jobs].length.should eql @length
218
+ @summary[:all_constrained][:wall_time].should eql @length * 3600
219
+ @summary[:all_constrained][:cpu_time].should eql @length * 100
220
+ @summary[:all_constrained][:successful].should eql 0.5
221
+ clipped_jobs = @summary[:clipped][:jobs].length
222
+ clipped_jobs.should eql 25
223
+ @summary[:clipped][:wall_time].should eql clipped_jobs * 3600 - 1800
224
+ @summary[:clipped][:cpu_time].should eql clipped_jobs * 100 - 50
225
+ @summary[:clipped][:memory_time].should eql clipped_jobs * 200 * 3600 - 100 * 3600
226
+ end
227
+
228
+ it "correctly handles summaries of empty sets" do
229
+ @summary[:empty].should eql({
230
+ :jobs => [],
231
+ :wall_time => 0,
232
+ :cpu_time => 0,
233
+ :memory_time => 0,
234
+ :successful => 0.0,
235
+ })
236
+ end
237
+
238
+ it "correctly handles jobs with zero wall time" do
239
+ job = @jobs.order(:start_time).first
240
+ wall_time = job.wall_time
241
+ begin
242
+ job.wall_time = 0
243
+ job.save!
244
+ @jobs.order(:start_time).limit(1).summary[:wall_time].should eql 0
245
+ ensure
246
+ job.wall_time = wall_time
247
+ job.save!
248
+ end
249
+ end
250
+
251
+ it "validates arguments" do
252
+ expect {
253
+ @jobs.summary(Time.local(2012), nil)
254
+ }.to raise_error('Max time must be specified with min time')
255
+ expect {
256
+ @jobs.summary(Time.local(2012), Time.local(2012) - 1)
257
+ }.to raise_error('Max time must be greater than or equal to min time')
258
+ end
259
+ end
260
+
261
+ it "validates fields" do
262
+ fields = {
263
+ :user => Bookie::Database::User.first,
264
+ :system => Bookie::Database::System.first,
265
+ :cpu_time => 100,
266
+ :start_time => Time.local(2012),
267
+ :wall_time => 1000,
268
+ :memory => 10000,
269
+ :exit_code => 0
270
+ }
271
+
272
+ job = Bookie::Database::Job.new(fields)
273
+ job.valid?.should eql true
274
+
275
+ fields.each_key do |field|
276
+ job = Bookie::Database::Job.new(fields)
277
+ job.method("#{field}=".intern).call(nil)
278
+ job.valid?.should eql false
279
+ end
280
+
281
+ [:cpu_time, :wall_time, :memory].each do |field|
282
+ job = Bookie::Database::Job.new(fields)
283
+ m = job.method("#{field}=".intern)
284
+ m.call(-1)
285
+ job.valid?.should eql false
286
+ m.call(0)
287
+ job.valid?.should eql true
288
+ end
289
+
290
+ job = Bookie::Database::Job.new(fields)
291
+ job.start_time = 0
292
+ job.valid?.should eql false
293
+ end
294
+ end
295
+
296
+ describe Bookie::Database::User do
297
+ describe "::find_or_create" do
298
+ before(:each) do
299
+ @group = Bookie::Database::Group.find_by_name('admin')
300
+ end
301
+
302
+ it "creates the user if needed" do
303
+ Bookie::Database::User.expects(:"create!").twice
304
+ user = Bookie::Database::User.find_or_create!('me', @group)
305
+ user = Bookie::Database::User.find_or_create!('me', @group, {})
306
+ end
307
+
308
+ it "returns the cached user if one exists" do
309
+ user = Bookie::Database::User.find_by_name('root')
310
+ known_users = {['root', user.group] => user}
311
+ Bookie::Database::User.find_or_create!('root', user.group, known_users).should equal user
312
+ end
313
+
314
+ it "queries the database when this user is not cached" do
315
+ user = Bookie::Database::User.find_by_name_and_group_id('root', 1)
316
+ known_users = {}
317
+ Bookie::Database::User.expects(:find_by_name_and_group_id).returns(user).twice
318
+ Bookie::Database::User.expects(:"create!").never
319
+ Bookie::Database::User.find_or_create!('root', user.group, known_users).should eql user
320
+ Bookie::Database::User.find_or_create!('root', user.group, nil).should eql user
321
+ known_users.should include ['root', user.group]
322
+ end
323
+ end
324
+
325
+ it "validates fields" do
326
+ fields = {
327
+ :group => Bookie::Database::Group.first,
328
+ :name => 'test',
329
+ }
330
+
331
+ Bookie::Database::User.new(fields).valid?.should eql true
332
+
333
+ fields.each_key do |field|
334
+ user = Bookie::Database::User.new(fields)
335
+ user.method("#{field}=".intern).call(nil)
336
+ user.valid?.should eql false
337
+ end
338
+
339
+ user = Bookie::Database::User.new(fields)
340
+ user.name = ''
341
+ user.valid?.should eql false
342
+ end
343
+ end
344
+
345
+ describe Bookie::Database::Group do
346
+ describe "::find_or_create" do
347
+ it "creates the group if needed" do
348
+ Bookie::Database::Group.expects(:"create!")
349
+ Bookie::Database::Group.find_or_create!('non_root')
350
+ end
351
+
352
+ it "returns the cached group if one exists" do
353
+ group = Bookie::Database::Group.find_by_name('root')
354
+ known_groups = {'root' => group}
355
+ Bookie::Database::Group.find_or_create!('root', known_groups).should equal group
356
+ end
357
+
358
+ it "queries the database when this group is not cached" do
359
+ group = Bookie::Database::Group.find_by_name('root')
360
+ known_groups = {}
361
+ Bookie::Database::Group.expects(:find_by_name).returns(group).twice
362
+ Bookie::Database::Group.expects(:"create!").never
363
+ Bookie::Database::Group.find_or_create!('root', known_groups).should eql group
364
+ Bookie::Database::Group.find_or_create!('root', nil).should eql group
365
+ known_groups.should include 'root'
366
+ end
367
+ end
368
+
369
+ it "validates the name field" do
370
+ group = Bookie::Database::Group.new(:name => nil)
371
+ group.valid?.should eql false
372
+ group.name = ''
373
+ group.valid?.should eql false
374
+ group.name = 'test'
375
+ group.valid?.should eql true
376
+ end
377
+ end
378
+
379
+ describe Bookie::Database::System do
380
+ it "correctly finds active systems" do
381
+ Bookie::Database::System.active_systems.length.should eql 3
382
+ end
383
+
384
+ it "correctly filters by name" do
385
+ Bookie::Database::System.by_name('test1').length.should eql 2
386
+ Bookie::Database::System.by_name('test2').length.should eql 1
387
+ Bookie::Database::System.by_name('test3').length.should eql 1
388
+ end
389
+
390
+ it "correctly filters by system type" do
391
+ ['Standalone', 'TORQUE cluster'].each do |type|
392
+ t = Bookie::Database::SystemType.find_by_name(type)
393
+ Bookie::Database::System.by_system_type(t).length.should eql 2
394
+ end
395
+ end
396
+
397
+ describe "::summary" do
398
+ before(:all) do
399
+ Time.expects(:now).returns(Time.local(2012) + 3600 * 40).at_least_once
400
+ @base_time = Time.local(2012)
401
+ @systems = Bookie::Database::System
402
+ @summary = Helpers::create_summaries(@systems, Time.local(2012))
403
+ @summary_wide = @systems.summary(Time.local(2012) - 3600, Time.local(2012) + 3600 * 40 + 3600)
404
+ end
405
+
406
+ it "produces correct summaries" do
407
+ system_total_wall_time = 3600 * (10 + 30 + 20 + 10)
408
+ system_clipped_wall_time = 3600 * (10 + 15 + 5) - 1800
409
+ system_wide_wall_time = system_total_wall_time + 3600 * 3
410
+ system_total_cpu_time = system_total_wall_time * 2
411
+ clipped_cpu_time = system_clipped_wall_time * 2
412
+ system_wide_cpu_time = system_wide_wall_time * 2
413
+ avg_mem = Float(1000000 * system_total_wall_time / (3600 * 40))
414
+ clipped_avg_mem = Float(1000000 * system_clipped_wall_time) / (3600 * 25 - 1800)
415
+ wide_avg_mem = Float(1000000 * system_wide_wall_time) / (3600 * 42)
416
+ @summary[:all][:avail_cpu_time].should eql system_total_cpu_time
417
+ @summary[:all][:avail_memory_time].should eql 1000000 * system_total_wall_time
418
+ @summary[:all][:avail_memory_avg].should eql avg_mem
419
+ @summary[:all_constrained][:avail_cpu_time].should eql system_total_cpu_time
420
+ @summary[:all_constrained][:avail_memory_time].should eql 1000000 * system_total_wall_time
421
+ @summary[:all_constrained][:avail_memory_avg].should eql avg_mem
422
+ @summary[:clipped][:avail_cpu_time].should eql clipped_cpu_time
423
+ @summary[:clipped][:avail_memory_time].should eql system_clipped_wall_time * 1000000
424
+ @summary[:clipped][:avail_memory_avg].should eql clipped_avg_mem
425
+ @summary_wide[:avail_cpu_time].should eql system_wide_cpu_time
426
+ @summary_wide[:avail_memory_time].should eql 1000000 * system_wide_wall_time
427
+ @summary_wide[:avail_memory_avg].should eql wide_avg_mem
428
+ @summary[:empty][:avail_cpu_time].should eql 0
429
+ @summary[:empty][:avail_memory_time].should eql 0
430
+ @summary[:empty][:avail_memory_avg].should eql 0.0
431
+ begin
432
+ @systems.all.each do |system|
433
+ unless system.id == 1
434
+ system.end_time = Time.now
435
+ system.save!
436
+ end
437
+ end
438
+ summary_all_systems_ended = @systems.summary()
439
+ summary_all_systems_ended.should eql @summary[:all]
440
+ summary_all_systems_ended = @systems.summary(Time.local(2012), Time.now + 3600)
441
+ s2 = @summary[:all].dup
442
+ s2[:avail_memory_avg] = Float(1000000 * system_total_wall_time) / (3600 * 41)
443
+ summary_all_systems_ended.should eql s2
444
+ ensure
445
+ @systems.all.each do |system|
446
+ unless system.id == 1
447
+ system.end_time = nil
448
+ system.save!
449
+ end
450
+ end
451
+ end
452
+ end
453
+
454
+ it "validates arguments" do
455
+ expect {
456
+ @systems.summary(Time.local(2012), nil)
457
+ }.to raise_error('Max time must be specified with min time')
458
+ expect {
459
+ @systems.summary(Time.local(2012), Time.local(2012) - 1)
460
+ }.to raise_error('Max time must be greater than or equal to min time')
461
+ end
462
+ end
463
+
464
+ describe "::find_active" do
465
+ before(:all) do
466
+ @FIELDS = {
467
+ :name => 'test',
468
+ :start_time => Time.local(2012),
469
+ :system_type => Bookie::Database::SystemType.first,
470
+ :cores => 2,
471
+ :memory => 1000000
472
+ }
473
+ end
474
+
475
+ it "raises an error if no versions or only old versions of this system exist" do
476
+ create_fields = @FIELDS.dup
477
+ create_fields[:end_time] = Time.local(2012) + 1
478
+ sys = Bookie::Database::System.create!(create_fields)
479
+ begin
480
+ expect {
481
+ Bookie::Database::System.find_active(@FIELDS)
482
+ }.to raise_error("There is no active system with hostname 'test' in the database.")
483
+ ensure
484
+ sys.delete
485
+ end
486
+ end
487
+
488
+ it "finds the existing active system" do
489
+ sys = Bookie::Database::System.create!(@FIELDS)
490
+ begin
491
+ Bookie::Database::System.find_active(@FIELDS).should eql sys
492
+ ensure
493
+ sys.delete
494
+ end
495
+ end
496
+
497
+ it "correctly detects conflicts" do
498
+ fields = @FIELDS.dup
499
+ fields[:cores] = 1
500
+ csys = Bookie::Database::System.create!(fields)
501
+ begin
502
+ expect {
503
+ Bookie::Database::System.find_active(@FIELDS)
504
+ }.to raise_error(Bookie::Database::System::SystemConflictError)
505
+ ensure
506
+ csys.delete
507
+ end
508
+ end
509
+ end
510
+
511
+ it "correctly decommissions" do
512
+ sys = Bookie::Database::System.active_systems.find_by_name('test1')
513
+ begin
514
+ sys.decommission(sys.start_time + 3)
515
+ sys.end_time.should eql sys.start_time + 3
516
+ ensure
517
+ sys.end_time = nil
518
+ sys.save!
519
+ end
520
+ end
521
+
522
+ it "validates fields" do
523
+ fields = {
524
+ :name => 'test',
525
+ :cores => 2,
526
+ :memory => 1000000,
527
+ :system_type => Bookie::Database::SystemType.first,
528
+ :start_time => Time.local(2012)
529
+ }
530
+
531
+ Bookie::Database::System.new(fields).valid?.should eql true
532
+
533
+ fields.each_key do |field|
534
+ system = Bookie::Database::System.new(fields)
535
+ system.method("#{field}=".intern).call(nil)
536
+ system.valid?.should eql false
537
+ end
538
+
539
+ system = Bookie::Database::System.new(fields)
540
+ system.name = ''
541
+ system.valid?.should eql false
542
+
543
+ [:cores, :memory].each do |field|
544
+ system = Bookie::Database::System.new(fields)
545
+ m = system.method("#{field}=".intern)
546
+ m.call(-1)
547
+ system.valid?.should eql false
548
+ m.call(0)
549
+ system.valid?.should eql true
550
+ end
551
+
552
+ system = Bookie::Database::System.new(fields)
553
+ system.start_time = 0
554
+ system.valid?.should eql false
555
+
556
+ system = Bookie::Database::System.new(fields)
557
+ system.end_time = Time.local(2012)
558
+ system.valid?.should eql true
559
+ system.end_time += 5
560
+ system.valid?.should eql true
561
+ system.end_time -= 10
562
+ system.valid?.should eql false
563
+ end
564
+ end
565
+
566
+ describe Bookie::Database::SystemType do
567
+ it "correctly maps memory stat type codes to/from symbols" do
568
+ systype = Bookie::Database::SystemType.new
569
+ systype.memory_stat_type = :avg
570
+ systype.memory_stat_type.should eql :avg
571
+ systype.read_attribute(:memory_stat_type).should eql Bookie::Database::MEMORY_STAT_TYPE[:avg]
572
+ systype.memory_stat_type = :max
573
+ systype.memory_stat_type.should eql :max
574
+ systype.read_attribute(:memory_stat_type).should eql Bookie::Database::MEMORY_STAT_TYPE[:max]
575
+ end
576
+
577
+ it "rejects unrecognized memory stat type codes" do
578
+ systype = Bookie::Database::SystemType.new
579
+ expect { systype.memory_stat_type = :invalid_type }.to raise_error("Unrecognized memory stat type 'invalid_type'")
580
+ expect { systype.memory_stat_type = nil }.to raise_error 'Memory stat type must not be nil'
581
+ systype.send(:write_attribute, :memory_stat_type, 10000)
582
+ expect { systype.memory_stat_type }.to raise_error("Unrecognized memory stat type code 10000")
583
+ end
584
+
585
+ it "creates the system type when needed" do
586
+ Bookie::Database::SystemType.expects(:'create!')
587
+ Bookie::Database::SystemType.find_or_create!('test', :avg)
588
+ end
589
+
590
+ it "raises an error if the existing type has the wrong memory stat type" do
591
+ systype = Bookie::Database::SystemType.create!(:name => 'test', :memory_stat_type => :max)
592
+ begin
593
+ expect {
594
+ Bookie::Database::SystemType.find_or_create!('test', :avg)
595
+ }.to raise_error("The recorded memory stat type for system type 'test' does not match the required type of 1")
596
+ expect {
597
+ Bookie::Database::SystemType.find_or_create!('test', :unrecognized)
598
+ }.to raise_error("Unrecognized memory stat type 'unrecognized'")
599
+ ensure
600
+ systype.delete
601
+ end
602
+ end
603
+
604
+ it "uses the existing type" do
605
+ systype = Bookie::Database::SystemType.create!(:name => 'test', :memory_stat_type => :avg)
606
+ begin
607
+ Bookie::Database::SystemType.expects(:'create!').never
608
+ Bookie::Database::SystemType.find_or_create!('test', :avg)
609
+ ensure
610
+ systype.delete
611
+ end
612
+ end
613
+
614
+ it "validates fields" do
615
+ systype = Bookie::Database::SystemType.new(:name => 'test')
616
+ expect { systype.valid? }.to raise_error('Memory stat type must not be nil')
617
+ systype.memory_stat_type = :unknown
618
+ systype.valid?.should eql true
619
+ systype.name = nil
620
+ systype.valid?.should eql false
621
+ systype.name = ''
622
+ systype.valid?.should eql false
623
+ end
624
+ end
625
+ end