Fix DB schema, write a basic unittest for the DB operations

This commit is contained in:
Arturo Filastò 2018-09-06 15:34:56 +02:00
parent ff2f973523
commit a518ca79da
6 changed files with 183 additions and 124 deletions

View File

@ -70,7 +70,7 @@ CREATE TABLE `results` (
`data_usage_down` INTEGER NOT NULL,
-- It's probably reasonable to set the maximum length to 260 as this is the
-- maximum length of file paths on windows.
`log_file_path` VARCHAR(260) NOT NULL
`measurement_dir` VARCHAR(260) NOT NULL
);
CREATE TABLE `measurements` (
@ -148,7 +148,7 @@ CREATE TABLE `measurements` (
-- we need for the measurement details views and some result views (ex. the
-- upload/download speed of NDT, the reason for blocking of a site,
-- etc.)
`test_keys` JSON,
`test_keys` JSON NOT NULL,
-- The cross table reference to JOIN the two tables together.
`result_id` INTEGER NOT NULL,
@ -166,5 +166,4 @@ CREATE TABLE `measurements` (
FOREIGN KEY (`url_id`) REFERENCES `urls`(`id`),
FOREIGN KEY(`network_id`) REFERENCES `networks` (`id`)
);
-- +migrate StatementEnd

View File

@ -130,105 +130,105 @@ func bindataDataDefaultconfigjson() (*asset, error) {
}
var _bindataDataMigrations1createmsmtresultssql = []byte(
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x59\x6d\x6f\xdb\x46\xf2\x7f\xef\x4f\x31\x30\x8a\xd6\xc6\x5f\x92\x93" +
"\xfc\xd3\xe0\xce\xd7\xa2\x70\x13\x25\xa7\x36\x96\x03\x59\xbe\x26\x38\x1c\xc4\x15\x39\x94\xb6\x5e\xee\x32\xfb\x20" +
"\x46\xf7\xe9\x0f\x33\xbb\xa4\x48\xe5\xc9\x01\x9a\x17\x8e\x44\xee\xce\xce\xe3\x6f\x7e\xb3\x1a\x8f\xe1\xff\x2a\xb9" +
"\xb1\xc2\x23\xbc\x30\x8d\x3e\xe9\x3f\xb8\xf5\xc2\x63\x85\xda\xff\x8a\x1b\xa9\x4f\x4e\x5e\x2c\x6e\xde\xc0\xf2\xea" +
"\xd7\xd7\x53\xc8\x2c\xba\xa0\xbc\xcb\xfe\x31\x78\x5a\xa1\x70\xc1\xf2\x9e\xe3\x57\xc1\xaa\xe3\x47\x1a\x7d\x63\xec" +
"\x3d\x3d\xfe\xf4\xb9\x53\x5d\x0c\xdf\xdc\xd5\x5f\x54\xf0\xf9\x62\x7a\xb5\x9c\x0e\x4e\x84\xb3\x13\x80\x4c\x16\x19" +
"\xcc\xe6\xcb\xe9\xab\xe9\x02\xde\x2c\x66\xd7\x57\x8b\x77\xf0\xfb\xf4\x1d\x5c\xdd\x2d\x6f\x66\xf3\xe7\x8b\xe9\xf5" +
"\x74\xbe\x1c\xd1\xca\x60\x55\x06\xff\xba\x5a\x3c\xff\xe7\xd5\xe2\xec\xc9\x8f\x3f\x9e\xc3\xfc\x66\x09\xf3\xbb\xd7" +
"\xaf\x47\x30\x1e\xc3\xdb\xb7\x6f\x41\x3a\xf0\x5b\xe9\x40\x19\xbd\x01\xd4\x26\x6c\xb6\xbf\xd0\xd6\x5c\x78\xdc\x18" +
"\xbb\x5f\xe5\xa6\xc0\x83\x90\x63\x11\xcb\x2d\x42\x2e\xbd\xfc\x2f\x6a\x25\xd6\xd0\xee\x02\xda\x05\xa5\xb1\xe0\xb7" +
"\x78\x02\x0f\xfb\x37\x1e\x83\x93\x1e\x27\xf0\x07\x42\x70\x48\x5b\xc1\x79\x2b\xf5\x06\xe6\x37\xf3\x29\x78\x03\x05" +
"\x6a\xe3\xbf\x45\xa0\x36\x70\xaf\x4d\xa3\x87\x9a\x4d\x4e\xd8\x44\x13\xb4\xff\xc8\xc2\x27\x07\x0b\x5b\x03\x7d\x63" +
"\x40\xa1\xf7\x68\x21\xed\x89\xf6\x35\x5b\x99\x6f\xd9\x7d\x0f\xd3\x68\x3c\x86\xbb\xc5\x6b\x58\x23\x39\xdb\x81\x37" +
"\x27\xe7\x31\x59\xfe\x40\xc8\x2d\x52\x12\x08\x70\x58\x0b\xce\x07\x2f\xd6\x2a\xfa\xb0\x4d\x2d\xfe\xf2\x04\x2c\x0a" +
"\x67\xb4\xbb\xa4\x9d\x8f\x27\xf0\xd2\x58\x70\xa6\x42\x30\x25\xbb\x6c\x27\xb1\x71\xd0\x6c\xd1\x22\x68\xc4\x82\x1f" +
"\x7a\xe3\x85\x02\x1d\xaa\x35\x5a\x5a\x98\x72\xbb\xe8\x64\x8f\x48\x9a\xf4\x3f\x38\xd8\x18\xf2\xb8\x37\xb0\x46\xa8" +
"\x42\xbe\x85\xca\x58\x04\x2c\x4b\x99\x4b\xd4\x9e\xde\xfc\x19\x9c\x07\x65\xcc\x7d\xa8\x59\x3a\x7b\x85\xc4\x5a\xd3" +
"\x38\x90\x3a\xfa\x64\x3c\x8e\x36\x4c\xe8\xd3\x93\x09\x9c\x55\xc6\x79\x90\x55\x6d\xac\x17\xda\x9f\x93\xd9\x8d\x88" +
"\x12\xc5\xce\xc8\x02\x8a\x50\x2b\x99\x0b\x4f\x0a\x08\x58\x07\x9d\x6f\x49\xaa\xd4\xa5\xb1\x95\xf0\xd2\x90\x64\xe1" +
"\x59\xd5\xa1\xa2\xb9\xa9\x2a\x7a\x6b\xc0\xe1\x0e\x2d\xd9\xda\x3a\x8d\x14\x0c\x0e\x2d\x6d\x31\x9a\x95\x99\x7e\x10" +
"\x55\xad\xf0\x32\xf9\xbe\x12\x7b\x68\xa4\xdb\xb2\x22\x45\x41\xff\x71\x4d\xc4\x08\xd0\x7e\x65\xf2\x78\x7c\x69\x4d" +
"\xd5\x3a\xba\xb6\x66\x8d\xf1\x09\x7d\x7d\xf5\xe6\x96\xe4\x19\xcb\x32\x5c\xa8\xc9\x4e\x0e\x99\x50\xca\x34\xac\x6b" +
"\xab\x8a\x37\x70\x9a\x1b\x6b\x31\xf7\xa7\x20\xa0\x92\x2e\x57\xc2\x39\x59\x4a\x2c\xa0\x87\x3b\x49\x60\x21\x1d\xf9" +
"\x24\x48\xb7\x25\x31\x6b\xf4\x0d\xa2\x86\x46\x96\x12\x84\x2e\xa0\x32\x6b\x49\x7e\x1e\x42\x46\x87\x48\xdf\x0a\x1b" +
"\x69\xe3\x4a\x8b\x0a\x87\xf8\xc1\x35\x7f\x1b\x6b\x92\xde\x82\xc5\xda\xa2\x43\xed\x5b\xf3\xfa\x7b\x53\x81\xac\xf7" +
"\x50\x60\x29\x82\xf2\x14\x82\xda\xd4\x41\x09\x8f\x05\xac\x85\xc3\xe2\x6b\x95\x43\x0e\xd0\x2c\xf9\xea\x76\x3e\x79" +
"\xc0\xea\x04\x1e\xbd\x42\xba\xc7\x3d\x39\xdc\x62\x89\x16\x75\x1e\x23\x9a\x32\xf5\x01\x02\x0f\xa9\xe0\x46\xb0\xc6" +
"\x5c\x90\xf8\x66\x98\x35\xa7\xa8\xad\xcc\xb7\xa7\x0f\x15\xd7\x48\x9f\xea\xaa\x10\x5e\xc4\x8a\x41\x28\x83\x0f\x16" +
"\x27\xfd\x10\xf8\x7d\xdd\x0b\xc1\xe3\x67\x31\x02\x37\x9a\xab\x9d\xe2\x3f\x4a\xc1\x27\x44\x83\x4c\xd6\x87\xc5\x4f" +
"\x1f\xf5\xb1\x3a\x06\xce\x58\x74\xe4\x9a\x18\xc1\x2e\x78\x31\xb7\x4d\x09\x42\x83\xac\x77\x4f\x29\xe7\x64\xbd\x7b" +
"\x46\x99\x6c\xd1\xb9\x87\xf8\x7d\xc9\x65\xa2\x37\x48\x35\x5e\x53\xa4\xa3\xb0\x4e\x08\x28\x79\x8f\x97\x0f\x90\xf4" +
"\xe8\xd1\xa3\x47\x97\x5f\xff\x33\x7a\x80\xa8\x98\x80\xd2\xc1\xff\xff\x1d\xf2\xad\xb0\x6c\x49\x26\x9c\xe6\x52\x38" +
"\x7b\xda\xf3\xd0\x5f\xd1\x11\x18\xcf\x87\x45\xd8\x52\x0b\xae\xc1\x6f\xa9\xc2\xe4\x54\xe9\x20\x17\x9a\x20\xce\xc4" +
"\xa0\x9f\x36\xb8\xa6\x36\xe9\x4e\x47\x70\x2a\x2b\xfa\x5b\xa3\x65\x80\xd4\x39\xd2\xd7\x4a\x16\x85\xc2\xb5\xf9\x70" +
"\x1a\xe3\x96\x79\x74\x7e\xb5\xb1\x26\xd4\x47\x25\xfd\xf8\xd9\xd0\x01\xc3\x02\x2a\x64\xc9\x15\xe3\xc1\x79\x61\xfd" +
"\xca\xcb\x0a\x19\x6e\x6c\xd0\xf4\x79\x50\x0d\x1d\x90\x2b\x67\x60\x2b\x76\xd8\x8a\xe3\x04\xf7\xa6\x45\x35\x4e\x74" +
"\xb3\x43\xbb\x45\x51\x90\x3d\xdc\xf8\x22\xe0\x5b\x64\xc8\xa4\x23\x8c\xdf\xa2\x85\x52\xe4\xde\x58\x17\x41\x3f\xc9" +
"\xdb\x18\x90\x9a\x11\x1a\x81\x0c\x9b\x1c\x7c\x25\x18\x60\xa8\x07\x88\xfd\x25\x64\xb7\x77\xd7\x67\x49\xd5\x73\x78" +
"\xb9\xb8\xb9\x86\x01\xa3\x83\x46\x2a\x05\x42\x35\x62\xef\xc8\xbf\x3f\xfd\xdc\x4a\xca\xd2\xae\xb8\xe9\x10\x41\xee" +
"\x5f\xf4\xc2\xc1\x4f\xe7\xd1\xb5\x07\xcf\x64\xf0\xe2\x6a\x39\x5d\xce\xae\xa7\x47\x2e\x6d\xa5\x65\xb0\x98\x5e\xbd" +
"\xee\xbd\x6c\x8f\xbb\x73\xc8\x3d\x47\xea\x82\x9a\x1f\x82\x2c\x0f\x9d\x62\x2b\x1c\x38\x02\x7b\xc6\x8d\xa8\x4b\xca" +
"\x24\xb7\xa2\x56\x8f\x45\x06\xcb\xd9\xfc\x1d\xe5\xf3\xe3\xf3\x4f\x88\xe7\x1c\xa2\x72\x84\x52\x89\x0d\x49\xfd\xe4" +
"\x69\x51\x34\x2d\x2c\x38\xd3\xb8\x5f\xe6\xc1\x52\x02\xa8\x3d\xc5\x5c\x4b\xbd\x99\x74\x67\xd3\xaa\xcf\x9c\xcc\x4b" +
"\x28\xee\xab\xe0\xc4\x06\x57\xa1\x3e\xe4\xfc\xe7\x57\x15\xa6\xd1\x9f\x5b\x37\x1e\xc3\x8c\xb8\x09\xb5\x5c\xb1\x26" +
"\x75\x98\x03\xc5\xfe\x4c\x3d\xdf\xb3\x0d\x95\xf8\x20\xab\x50\x81\x42\xbd\xf1\x0c\xcc\x4f\x9e\x3d\x02\x91\x28\x2e" +
"\x53\xdd\x2e\x2f\x8f\xd6\x9a\x12\x4a\xa9\x10\x6a\xe1\xb7\xc4\x13\xa0\x91\xba\x30\x4d\x82\xbe\x4c\x99\xcd\x8a\xde" +
"\xaf\xe8\x7d\x0f\x1a\x9e\xf5\x40\xf6\x13\xd5\x3f\x4c\xb8\xbf\x08\x02\x2e\xdb\x57\xa5\xc8\x71\x6d\xcc\xfd\xaa\x42" +
"\xe7\x50\x6f\xd0\xb6\x6f\x3c\x2a\xdc\x58\x51\x9d\x74\x38\x28\xbc\x13\x75\xdd\x7e\xdf\x7a\x5f\xaf\xa8\x02\xd1\xae" +
"\x4a\x89\xaa\x58\x55\x42\x4b\x6e\xcc\xd2\xe8\xc1\x2a\xa9\x77\x42\xc9\x62\x65\xf1\x7d\x20\x1c\x51\x52\xf7\x6a\xdb" +
"\x6d\xdb\xcf\xba\xf0\x3d\xb4\x19\xe2\xcc\xb3\xa7\x1f\xa5\xc7\x5f\x51\x38\x2f\xe3\x7c\x01\x75\xb0\xb5\x71\x8c\x8e" +
"\x89\x5d\xb4\x6c\x24\x52\xb4\x3e\x7f\x4c\xad\x36\x15\x75\x2b\x89\x39\xf3\x08\xf6\x26\x80\xdb\x9a\xa0\x0a\xa8\x65" +
"\x7e\x1f\x9b\xb2\xb4\xce\xf7\x91\xa3\x15\xf1\xdb\xcd\x6c\x0e\xce\x58\xa6\x32\xfb\x56\xd2\xc1\xae\x0e\x98\xde\x99" +
"\x40\x35\xf5\x83\x67\x5c\xe4\xbd\x9b\x20\xac\xd0\x1e\x91\xa1\x0d\x88\xb2\xee\xe1\x4c\xd6\x23\x10\x4e\x8f\xda\x9e" +
"\x32\x1a\xb0\xa9\xf3\x56\x5e\xcc\x63\x70\xc4\xb0\xa4\x06\x01\xa7\x7d\xed\x1c\x12\xa5\x74\xce\xe4\x92\x59\x16\x61" +
"\x32\x9c\x46\x7b\xdb\x86\xd0\x8a\xed\x67\xe2\xc7\xee\x9d\x1b\x1f\xe7\x8f\x8d\x51\x42\x6f\x2e\x09\xe6\x5b\xf4\x60" +
"\x4b\x1c\x4d\xac\xbd\xd6\x94\x45\x4c\x20\xfc\xce\x44\xee\xe5\x0e\xb3\x11\x38\x73\xd2\x67\x3e\xd2\x01\xbe\x0f\x72" +
"\x27\x54\x9a\x25\x18\x6d\xd6\xc8\x11\xb3\x81\x81\xa7\x14\xca\x1d\xdc\x97\xf1\x31\x19\x2c\xa7\x6f\x53\x55\x3c\x00" +
"\x7e\x52\x9f\x8e\x30\xd1\x29\x2c\xa0\xc0\x88\x7a\x05\x48\xb7\x0a\xb5\x32\xa2\xc0\x82\x81\x71\x04\x52\x3b\x9f\x9a" +
"\x12\x0f\x38\xc1\x49\xbd\x39\x38\x3d\x2d\x5f\x95\x42\x2a\x2c\x46\x31\x0c\xc2\xb7\x54\x50\x9b\x14\xdf\x4e\x2a\x23" +
"\x52\x2f\x32\x45\xe8\x0a\x87\x83\xe2\xd0\xfb\x01\xa4\xb6\x3b\x1f\x08\xe8\xc7\xf2\xa3\x62\x4c\x75\x83\xe6\x28\x74" +
"\x5d\x24\x25\x35\x85\x8a\x7a\xba\xe5\x65\xad\x3c\x8b\x63\xda\x20\xfd\x41\x93\x28\xea\x4b\xf0\x4e\x2b\x82\xc5\x55" +
"\xe5\x36\x47\x23\xc2\xc9\x91\x3d\x0f\x10\xd6\x5b\xf8\x25\x99\xd4\x05\xdc\xc7\x0d\x8c\xa3\xc0\xc9\x55\x0b\xeb\x65" +
"\x1e\x94\xb0\x03\xc7\x50\x0f\x5d\x53\x0f\x4d\x96\x0a\x5d\x1c\x72\x12\x2d\x96\x26\xf1\x92\xbb\x19\x23\xad\x17\xf7" +
"\x98\xb2\x95\x98\x86\xc8\xe3\x7c\xeb\x0d\xa0\x64\x5e\xb2\x95\x05\x82\xf4\xdd\xec\x77\xf0\x24\xf7\x50\x42\x13\x9e" +
"\x03\x63\x57\xe2\xe2\x56\x28\x9c\xa7\x41\xae\x9b\x29\xc5\x5a\x2a\xe9\xd3\x68\x32\x88\x40\xba\x9a\x29\x0c\xe5\x16" +
"\x13\xaa\x96\x5d\xa5\x2c\xee\x8d\x32\x26\xc1\x19\x0b\xe8\x19\xfd\x4b\x17\x05\x8b\x36\xe8\x6f\x48\x29\x87\x76\x87" +
"\x76\xec\xc8\xc6\xc8\xc8\x56\xb2\x00\x8b\x3e\x58\xcd\x50\x97\x46\x7e\xa5\x90\xd8\xd9\x04\x7e\xdd\x0f\x4b\xe5\xb0" +
"\xe9\x7b\x90\xba\x0e\x3e\x02\x2b\x79\xf6\x7d\x20\x5f\xb0\xf5\xb5\x24\xe5\x4b\xf4\xe9\x0a\xa5\xaf\x7c\xe7\x86\xe9" +
"\x87\xee\xe3\xab\xe9\x92\x1b\x92\xbb\xbc\xb8\x10\xb5\x9c\x18\xa3\xe5\x44\x1a\xfa\x7c\xb1\x7b\x7c\xd1\xef\xb4\xbf" +
"\xf0\xa9\x3f\x7f\x37\x9b\xbf\xb9\x5b\x7e\xdf\xa9\xf3\xf3\x77\x8b\xe9\x9b\x9b\xc5\x72\x35\x7b\x71\x90\xef\xad\xc8" +
"\x7d\x0f\xe8\xa5\xc7\xea\x30\xd3\x27\xfa\xfe\xef\xff\x64\xa0\xa4\xf3\x6d\x51\xe9\xa8\x77\xd7\x88\xfb\x7d\x7e\xc5" +
"\x97\x6e\xde\xc0\x26\x91\x92\xdf\x6e\x6f\xe6\xf1\xca\x60\x68\x24\x8d\xa0\x3d\xf2\x8a\x2e\x8e\x15\x3b\xa1\x02\x3a" +
"\x38\xcb\x3a\xbd\xb3\x11\x64\x6c\x51\x76\x0e\xc2\x72\x45\x97\x41\x1d\xbc\x27\x3a\x4a\xd3\x13\xce\x45\x41\x89\x2f" +
"\x94\x45\x51\xec\x63\x01\xd4\xd6\xe4\xc4\x15\xba\x30\xd6\xb2\x46\xea\xe8\xa3\x1e\x1e\xc8\xaa\x56\x51\x48\xae\x50" +
"\xe8\x50\xf3\x64\x98\xc4\x74\xe8\xd6\x77\x78\x02\x8e\x83\xc6\x1f\x5f\x1a\xf4\x69\x0c\x4f\x52\x0d\xb9\x51\x9b\x96" +
"\xf4\x33\xf9\x6a\x0b\xf5\x2b\x93\xdd\x78\x9c\xae\xcb\x8a\x49\x02\x9b\x60\xd5\x57\x9a\x59\x9b\xe1\x04\xd3\x7b\xf4" +
"\xc4\x86\x51\xd0\xb8\xdd\xde\xe6\x74\x09\x3d\x82\x75\x60\x54\x27\x5f\xd7\x4a\x30\xef\x4d\x57\x43\x83\x56\x26\x7c" +
"\xbc\x77\xab\x8d\x3c\xb0\x02\x8d\xc2\xf6\x06\xf9\x38\x77\x23\x5e\x76\xb9\xbb\x91\x7e\x1b\xd6\x93\xdc\x54\x17\x94" +
"\xc2\x17\x6d\x04\x2e\xd6\xca\xac\x2f\x2a\xe1\x3c\xda\x8b\xc2\xe4\x8e\x5f\x8f\x43\x90\xc5\xa4\x2a\xe0\xfb\x3e\x29" +
"\xfb\xa2\x1c\xe9\x5c\x40\x77\xf1\xf4\x6f\xd1\x35\xfd\xd4\x4c\x2e\x22\x3e\x76\xec\x99\x04\xa6\xae\xb5\x23\x17\x91" +
"\x50\x09\x68\xe7\x4d\x9e\xb6\x46\x31\xb1\x04\xdf\xd4\x92\x3f\x69\xa8\x57\x1d\xfb\x59\x2b\x93\xdf\x53\x73\xa4\x2e" +
"\x4e\x08\xa8\x61\x76\xcd\x1b\xdb\x31\x23\x7d\x75\x34\xa3\xb9\x84\x04\xf5\x97\x05\xc9\x92\xaf\xc8\xd2\x50\x0b\x8d" +
"\x70\x50\xa0\xc7\x9c\xe3\xdf\xe3\x58\x94\x5d\x19\xb1\xb2\x0c\x04\x64\xcf\x6f\xee\xe6\xcb\xb3\xf3\xac\x2b\x3d\x2e" +
"\xac\x23\xfe\x17\xa1\x3a\x15\xab\xe8\xee\x31\x8f\xb4\x80\x68\xbf\xb1\xdd\x83\xd9\x35\xa9\xed\x3a\x8c\x15\xda\x54" +
"\x42\xed\xfb\x28\xfb\x89\x01\x4c\x83\xa9\xc5\xfb\x90\x20\xc1\x79\x1b\x72\xca\x93\x51\xba\xac\x6d\x88\x51\x51\x2b" +
"\xea\xdf\xe6\x32\x9b\xbe\xc7\x7d\x47\x55\x9b\x74\xab\x9b\x2e\xd7\x87\x0c\x03\xbd\x90\xca\xa5\x2b\x60\x02\x2b\x16" +
"\xd5\x6b\x4b\x0e\xce\xf0\xc3\xa4\xdf\xb3\x62\x41\x5f\xd0\xf4\x45\x1f\xc0\xd5\x24\xdd\x94\x30\x7f\xb1\x1c\x25\x5f" +
"\x31\x89\x2a\x5b\xfb\xa9\x1c\x38\x33\xc8\x2d\x1d\xdd\x42\x9f\x4f\xce\x7b\x13\x00\xe9\x9c\xb1\xa5\x7d\x4f\x20\xe4" +
"\xd6\xb8\xf6\x6a\x75\xd0\xc7\x98\x4f\xfb\x74\xb9\x12\xef\xdb\xc0\x9b\x0d\x52\xc7\xed\x00\x86\x0c\xf9\x5c\xa5\x7f" +
"\x3c\xf0\xee\x84\x95\x7c\x10\x73\x06\xa9\x3d\x5a\x2d\x94\xe2\x9e\x4b\xc0\x1f\x19\x3e\x8d\x74\x6d\x23\x35\x7a\x5c" +
"\x48\x77\xff\x09\x44\x75\x93\x3f\x9d\xd1\x13\x98\x79\xa6\x7b\x15\x71\x04\x87\xda\xb1\xee\x8d\xa5\x72\x20\x26\x1b" +
"\x87\x48\xb4\x80\x7c\x2b\x74\x18\x0c\xb6\xc6\xb0\xe7\xae\x7f\xe7\xc0\xd4\x16\x77\xe9\xda\xb4\x25\x12\x24\xa4\x85" +
"\x9a\x28\xc7\x68\x62\x0c\xf7\xe9\x1a\xab\x12\x07\x61\xc4\x03\x2a\xa1\xf7\x03\x0d\xf9\xdc\x92\x6f\x82\xfb\x78\xfc" +
"\xb5\xb9\x35\xc5\xe7\xe5\xcd\x62\x3a\x7b\x35\xe7\x51\xf4\xac\xe7\xea\x73\x58\x4c\x5f\x4e\x17\xd3\xf9\xf3\xe9\xed" +
"\xe1\x3e\xeb\x8c\xc6\xd8\xf3\x04\xd4\x37\x73\x78\x31\x7d\x3d\x5d\x4e\xe1\xf9\xd5\xed\xf3\xab\x17\x53\x7a\x72\xf7" +
"\x86\xe6\xba\xf6\x09\x37\x81\x59\x49\xe9\x5b\xa0\x42\x1f\x69\x0c\xe7\x65\x9f\xe4\x3c\xf4\xa7\x9d\xe4\x07\xa1\xd4" +
"\x71\x11\xb8\xf4\x8b\x40\x3c\xa5\xa0\xe9\xbf\x41\xa5\x26\x9f\xb0\x31\x75\x8d\xa1\x81\xfc\x43\x5b\xb4\x6e\x74\xbc" +
"\xe7\xac\x3f\x39\x0d\xb7\xf5\x2e\xdb\xa3\x67\xce\xbf\xf4\x3b\xe0\xff\x02\x00\x00\xff\xff\x29\x5f\x48\x5d\xaa\x1c" +
"\x00\x00")
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x59\x6d\x6f\xdb\xc6\xb2\xfe\xee\x5f\x31\x30\x8a\xd6\xc6\x95\xe4\x24" +
"\x37\x0d\xee\x75\x5b\x14\xae\xad\xe4\xa8\x8d\xe5\x40\x96\x4f\x13\x1c\x1c\x88\x2b\x72\x28\x6d\xbd\xdc\x65\xf6\x45" +
"\x8a\xce\xaf\x3f\x98\xd9\x25\x45\xca\x4e\xe2\x00\xcd\x07\x47\x22\x77\x67\xe7\xf5\x99\x67\x56\xc3\x21\xfc\x4f\x25" +
"\x57\x56\x78\x84\x2b\xb3\xd5\x47\xdd\x07\xb7\x5e\x78\xac\x50\xfb\xdf\x70\x25\xf5\xd1\xd1\xd5\xec\xe6\x1d\xcc\x2f" +
"\x7e\x7b\x3b\x86\xcc\xa2\x0b\xca\xbb\xec\xa7\xde\xd3\x0a\x85\x0b\x96\xf7\x1c\xbe\x0a\x56\x1d\x3e\xd2\xe8\xb7\xc6" +
"\xde\xd3\xe3\xc7\xcf\x1d\xeb\xa2\xff\xe6\xae\xfe\xa2\x82\x97\xb3\xf1\xc5\x7c\xdc\x3b\x11\x4e\x8e\x00\x32\x59\x64" +
"\x30\x99\xce\xc7\x6f\xc6\x33\x78\x37\x9b\x5c\x5f\xcc\x3e\xc0\x1f\xe3\x0f\x70\x71\x37\xbf\x99\x4c\x2f\x67\xe3\xeb" +
"\xf1\x74\x3e\xa0\x95\xc1\xaa\x0c\xfe\x79\x31\xbb\xfc\xc7\xc5\xec\xe4\xc5\x8f\x3f\x9e\xc2\xf4\x66\x0e\xd3\xbb\xb7" +
"\x6f\x07\x30\x1c\xc2\xfb\xf7\xef\x41\x3a\xf0\x6b\xe9\x40\x19\xbd\x02\xd4\x26\xac\xd6\xbf\xd2\xd6\x5c\x78\x5c\x19" +
"\xbb\x5b\xe4\xa6\xc0\xbd\x90\x43\x11\xf3\x35\x42\x2e\xbd\xfc\x0f\x6a\x25\x96\xd0\xec\x02\xda\x05\xa5\xb1\xe0\xd7" +
"\x78\x04\x4f\xfb\x37\x1c\x82\x93\x1e\x47\xf0\x27\x42\x70\x48\x5b\xc1\x79\x2b\xf5\x0a\xa6\x37\xd3\x31\x78\x03\x05" +
"\x6a\xe3\xbf\x45\xa0\x36\x70\xaf\xcd\x56\xf7\x35\x1b\x1d\xb1\x89\x26\x68\xff\xc0\xc2\x17\x7b\x0b\x1b\x03\xfd\xd6" +
"\x80\x42\xef\xd1\x42\xda\x13\xed\xdb\xae\x65\xbe\x66\xf7\x3d\x4d\xa3\xe1\x10\xee\x66\x6f\x61\x89\xe4\x6c\x07\xde" +
"\x1c\x9d\xc6\x64\xf9\x13\x21\xb7\x48\x49\x20\xc0\x61\x2d\x38\x1f\xbc\x58\xaa\xe8\xc3\x26\xb5\xf8\xcb\x0b\xb0\x28" +
"\x9c\xd1\xee\x9c\x76\x3e\x1f\xc1\x6b\x63\xc1\x99\x0a\xc1\x94\xec\xb2\x8d\xc4\xad\x83\xed\x1a\x2d\x82\x46\x2c\xf8" +
"\xa1\x37\x5e\x28\xd0\xa1\x5a\xa2\xa5\x85\x29\xb7\x8b\x56\xf6\x80\xa4\x49\xff\x83\x83\x95\x21\x8f\x7b\x03\x4b\x84" +
"\x2a\xe4\x6b\xa8\x8c\x45\xc0\xb2\x94\xb9\x44\xed\xe9\xcd\x5f\xc1\x79\x50\xc6\xdc\x87\x9a\xa5\xb3\x57\x48\xac\x35" +
"\x5b\x07\x52\x47\x9f\x0c\x87\xd1\x86\x11\x7d\x7a\x31\x82\x93\xca\x38\x0f\xb2\xaa\x8d\xf5\x42\xfb\x53\x32\x7b\x2b" +
"\xa2\x44\xb1\x31\xb2\x80\x22\xd4\x4a\xe6\xc2\x93\x02\x02\x96\x41\xe7\x6b\x92\x2a\x75\x69\x6c\x25\xbc\x34\x24\x59" +
"\x78\x56\xb5\xaf\x68\x6e\xaa\x8a\xde\x1a\x70\xb8\x41\x4b\xb6\x36\x4e\x23\x05\x83\x43\x4b\x5b\x8c\x66\x65\xc6\x9f" +
"\x44\x55\x2b\x3c\x4f\xbe\xaf\xc4\x0e\xb6\xd2\xad\x59\x91\xa2\xa0\xff\xb8\x26\x62\x04\x68\xbf\x32\x79\x3c\xbe\xb4" +
"\xa6\x6a\x1c\x5d\x5b\xb3\xc4\xf8\x84\xbe\xbe\x79\x77\x4b\xf2\x8c\x65\x19\x2e\xd4\x64\x27\x87\x4c\x28\x65\xb6\xac" +
"\x6b\xa3\x8a\x37\x70\x9c\x1b\x6b\x31\xf7\xc7\x20\xa0\x92\x2e\x57\xc2\x39\x59\x4a\x2c\xa0\x83\x3b\x49\x60\x21\x1d" +
"\xf9\x24\x48\xb7\x26\x31\x4b\xf4\x5b\x44\x0d\x5b\x59\x4a\x10\xba\x80\xca\x2c\x25\xf9\xb9\x0f\x19\x2d\x22\x7d\x2b" +
"\x6c\xa4\x8d\x0b\x2d\x2a\xec\xe3\x07\xd7\xfc\x6d\xac\x49\x7a\x0b\x16\x6b\x8b\x0e\xb5\x6f\xcc\xeb\xee\x4d\x05\xb2" +
"\xdc\x41\x81\xa5\x08\xca\x53\x08\x6a\x53\x07\x25\x3c\x16\xb0\x14\x0e\x8b\xaf\x55\x0e\x39\x40\xb3\xe4\x8b\xdb\xe9" +
"\xe8\x09\xab\x13\x78\x74\x0a\xe9\x1e\x77\xe4\x70\x8b\x25\x5a\xd4\x79\x8c\x68\xca\xd4\x27\x08\xdc\xa7\x82\x1b\xc0" +
"\x12\x73\x41\xe2\xb7\xfd\xac\x39\x46\x6d\x65\xbe\x3e\x7e\xaa\xb8\xad\xf4\xa9\xae\x0a\xe1\x45\xac\x18\x84\x32\xf8" +
"\x60\x71\xd4\x0d\x81\xdf\xd5\x9d\x10\x3c\x7f\x15\x23\x70\xa3\xb9\xda\x29\xfe\x83\x14\x7c\x42\x34\xc8\x64\xbd\x5f" +
"\xfc\xf2\x59\x17\xab\x63\xe0\x8c\x45\x47\xae\x89\x11\x6c\x83\x17\x73\xdb\x94\x20\x34\xc8\x7a\xf3\x92\x72\x4e\xd6" +
"\x9b\x57\x94\xc9\x16\x9d\x7b\x8a\xdf\xe7\x5c\x26\x7a\x85\x54\xe3\x35\x45\x3a\x0a\x6b\x85\x80\x92\xf7\x78\xfe\x04" +
"\x49\xcf\x9e\x3d\x7b\x76\xfe\xf5\x3f\x83\x27\x88\x8a\x09\x28\x1d\xfc\xef\xff\x43\xbe\x16\x96\x2d\xc9\x84\xd3\x5c" +
"\x0a\x27\x2f\x3b\x1e\xfa\x3b\x3a\x02\xe3\x79\xbf\x08\x1b\x6a\xc1\x35\xf8\x2d\x55\x98\x9c\x2a\x1d\xe4\x42\x13\xc4" +
"\x99\x18\xf4\xe3\x2d\x2e\xa9\x4d\xba\xe3\x01\x1c\xcb\x8a\xfe\xd6\x68\x19\x20\x75\x8e\xf4\xb5\x92\x45\xa1\x70\x69" +
"\x3e\x1d\xc7\xb8\x65\x1e\x9d\x5f\xac\xac\x09\xf5\x41\x49\x3f\x7f\xd5\x77\x40\xbf\x80\x0a\x59\x72\xc5\x78\x70\x5e" +
"\x58\xbf\xf0\xb2\x42\x86\x1b\x1b\x34\x7d\xee\x55\x43\x0b\xe4\xca\x19\x58\x8b\x0d\x36\xe2\x38\xc1\xbd\x69\x50\x8d" +
"\x13\xdd\x6c\xd0\xae\x51\x14\x64\x0f\x37\xbe\x08\xf8\x16\x19\x32\xe9\x08\xe3\xd7\x68\xa1\x14\xb9\x37\xd6\x45\xd0" +
"\x4f\xf2\x56\x06\xa4\x66\x84\x46\x20\xc3\x46\x7b\x5f\x09\x06\x18\xea\x01\x62\x77\x0e\xd9\xed\xdd\xf5\x49\x52\xf5" +
"\x14\x5e\xcf\x6e\xae\xa1\xc7\xe8\x60\x2b\x95\x02\xa1\xb6\x62\xe7\xc8\xbf\x3f\xff\xd2\x48\xca\xd2\xae\xb8\x69\x1f" +
"\x41\xee\x5f\xf4\xc2\xc1\xcf\xa7\xd1\xb5\x7b\xcf\x64\x70\x75\x31\x1f\xcf\x27\xd7\xe3\x03\x97\x36\xd2\x32\x98\x8d" +
"\x2f\xde\x76\x5e\x36\xc7\xdd\x39\xe4\x9e\x23\x75\x41\xcd\x0f\x41\x96\xfb\x4e\xb1\x16\x0e\x1c\x81\x3d\xe3\x46\xd4" +
"\x25\x65\x92\x5b\x50\xab\xc7\x22\x83\xf9\x64\xfa\x81\xf2\xf9\xf9\xe9\x23\xe2\x39\x87\xa8\x1c\xa1\x54\x62\x45\x52" +
"\x1f\x3d\x2d\x8a\xa6\x85\x05\x67\x1a\xf7\xcb\x3c\x58\x4a\x00\xb5\xa3\x98\x6b\xa9\x57\xa3\xf6\x6c\x5a\xf5\x99\x93" +
"\x79\x09\xc5\x7d\x11\x9c\x58\xe1\x22\xd4\xfb\x9c\xff\xfc\xaa\xc2\x6c\xf5\xe7\xd6\x0d\x87\x30\x21\x6e\x42\x2d\x57" +
"\x2c\x49\x1d\xe6\x40\xb1\x3f\x53\xcf\xf7\x6c\x43\x25\x3e\xc9\x2a\x54\xa0\x50\xaf\x3c\x03\xf3\x8b\x57\xcf\x40\x24" +
"\x8a\xcb\x54\xb7\xcd\xcb\x83\xb5\xa6\x84\x52\x2a\x84\x5a\xf8\x35\xf1\x04\xd8\x4a\x5d\x98\x6d\x82\xbe\xee\x2c\xb0" +
"\x28\xa4\xed\x80\xc3\xab\x0e\xcc\x3e\x52\xff\xfd\x94\xfb\x9b\x40\xe0\xbc\x79\x55\x8a\x1c\x97\xc6\xdc\x2f\x2a\x74" +
"\x0e\xf5\x0a\x6d\xf3\xc6\xa3\xc2\x95\x15\xd5\x51\x8b\x84\xc2\x3b\x51\xd7\xcd\xf7\xb5\xf7\xf5\x82\x6a\x10\xed\xa2" +
"\x94\xa8\x8a\x45\x25\xb4\xe4\xd6\x2c\x8d\xee\xad\x92\x7a\x23\x94\x2c\x16\x16\x3f\x06\x42\x12\x25\x75\xa7\xba\xdd" +
"\xba\xf9\xac\x0b\xdf\xc1\x9b\x3e\xd2\xbc\x7a\xf9\x20\x41\xfe\x8e\xd2\x79\x1d\x27\x0c\xa8\x83\xad\x8d\x63\x7c\x4c" +
"\xfc\xa2\xe1\x23\x91\xa4\x75\x19\x64\x6a\xb6\xa9\xac\x1b\x49\xcc\x9a\x07\xb0\x33\x01\xdc\xda\x04\x55\x40\x2d\xf3" +
"\xfb\xd8\x96\xa5\x75\xbe\x8b\x1d\x8d\x88\xdf\x6f\x26\x53\x70\xc6\x32\x99\xd9\x35\x92\xf6\x76\xb5\xd0\xf4\xc1\x04" +
"\xaa\xaa\x1f\x3c\x23\x23\xef\x5d\x05\x61\x85\xf6\x88\x0c\x6e\x40\xa4\x75\x07\x27\xb2\x1e\x80\x70\x7a\xd0\x74\x95" +
"\x41\x8f\x4f\x9d\x36\xf2\x62\x26\x83\x23\x8e\x25\x35\x08\x38\xee\x6a\xe7\x90\x48\xa5\x73\x26\x97\xcc\xb3\x08\x95" +
"\xe1\x38\xda\xdb\xb4\x84\x46\x6c\x37\x13\x1f\xba\x77\x6a\x7c\x9c\x40\x56\x46\x09\xbd\x3a\x27\xa0\x6f\xf0\x83\x2d" +
"\x71\x34\xb3\x76\x9a\x53\x16\x51\x81\x10\x3c\x13\xb9\x97\x1b\xcc\x06\xe0\xcc\x51\x97\xfb\x48\x07\xf8\x31\xc8\x8d" +
"\x50\x69\x9a\x60\xbc\x59\x22\x47\xcc\x06\x86\x9e\x52\x28\xb7\x77\x5f\xc6\xc7\x64\x30\x1f\xbf\x4f\x55\xf1\x04\x00" +
"\x4a\x9d\x3a\x02\x45\xab\xb0\x80\x02\x23\xee\x15\x20\xdd\x22\xd4\xca\x88\x02\x0b\x86\xc6\x01\x48\xed\x7c\x6a\x4b" +
"\x3c\xe2\x04\x27\xf5\x6a\xef\xf4\xb4\x7c\x51\x0a\xa9\xb0\x18\xc4\x30\x08\xdf\x90\x41\x6d\x52\x7c\x5b\xa9\x8c\x49" +
"\x9d\xc8\x14\xa1\x2d\x1c\x0e\x8a\x43\xef\x7b\xa0\xda\xec\x7c\x22\xa4\x1f\xca\x8f\x8a\x31\xd9\x0d\x9a\xa3\xd0\xf6" +
"\x91\x94\xd4\x14\x2a\xea\xea\x96\x97\x35\xf2\x2c\x0e\x69\x83\xf4\x7b\x4d\xa2\xa8\x2f\x01\x3c\xad\x08\x16\x17\x95" +
"\x5b\x1d\x0c\x09\x47\x07\xf6\x3c\x41\x58\x67\xe1\x97\x64\x52\x1f\x70\x0f\x5b\x18\x47\x81\x93\xab\x16\xd6\xcb\x3c" +
"\x28\x61\x7b\x8e\xa1\x2e\xba\xa4\x2e\x9a\x2c\x15\xba\xd8\xe7\x24\x5a\x2c\x4d\x62\x26\x77\x13\x46\x5a\x2f\xee\x31" +
"\x65\x2b\x71\x0d\x91\xc7\x09\xd7\x1b\x40\xc9\xcc\x64\x2d\x0b\x04\xe9\xdb\xe9\x6f\xef\x49\xee\xa2\x84\x26\x3c\x09" +
"\xc6\xbe\xc4\xc5\xad\x50\x38\x4f\xa3\x5c\x3b\x55\x8a\xa5\x54\xd2\xa7\xe1\xa4\x17\x81\x74\x39\x53\x18\xca\x2d\xa6" +
"\x54\x0d\xbf\x4a\x59\xdc\x19\x66\x4c\x82\x33\x16\xd0\x31\xfa\xd7\x36\x0a\x16\x6d\xd0\xdf\x90\x52\x0e\xed\x06\xed" +
"\xd0\x91\x8d\x91\x93\x2d\x64\x01\x16\x7d\xb0\x9a\xa1\x2e\x0d\xfd\x4a\x21\xf1\xb3\x11\xfc\xb6\xeb\x97\xca\x7e\xd3" +
"\xf7\x20\x75\x1d\x7c\x04\x56\xf2\xec\xc7\x40\xbe\x60\xeb\x6b\x49\xca\x97\xe8\xd3\x25\x4a\x57\xf9\xd6\x0d\xe3\x4f" +
"\xed\xc7\x37\xe3\x39\x37\x24\x77\x7e\x76\x26\x6a\x39\x32\x46\xcb\x91\x34\xf4\xf9\x6c\xf3\xfc\xac\xdb\x69\x7f\xe5" +
"\x53\x7f\xf9\x6e\x32\x7d\x77\x37\xff\xbe\x55\xe7\x97\xef\x66\xe3\x77\x37\xb3\xf9\x62\x72\xb5\x97\xef\xad\xc8\x7d" +
"\x07\xe8\xa5\xc7\x6a\x3f\xd5\x27\x02\xff\xaf\x7f\x67\xa0\xa4\xf3\x4d\x51\xe9\xa8\x77\xdb\x88\x7b\x04\x81\xaf\xdd" +
"\xbc\x81\x55\xa2\x25\xbf\xdf\xde\x4c\xe3\xa5\x41\xdf\x48\x1a\x42\x3b\xf4\x15\x5d\x1c\x2c\x36\x42\x05\x74\x70\x92" +
"\xb5\x7a\x67\x03\xc8\xd8\xa2\xec\x14\x84\xe5\x8a\x2e\x83\xda\x7b\x4f\xb4\xa4\xa6\x23\x9c\x8b\x82\x12\x5f\x28\x8b" +
"\xa2\xd8\xc5\x02\xa8\xad\xc9\x89\x2b\xb4\x61\xac\x65\x8d\xd4\xd1\x07\x1d\x3c\x90\x55\xad\xa2\x90\x5c\xa1\xd0\xa1" +
"\xe6\xd9\x30\x89\x69\xd1\xad\xeb\xf0\x04\x1c\x7b\x8d\x1f\x5e\x1b\x74\x69\x0c\xcf\x52\x5b\x72\xa3\x36\x0d\xed\x67" +
"\xfa\xd5\x14\xea\x57\x66\xbb\xe1\x30\x5d\x98\x15\xa3\x04\x36\xc1\xaa\xaf\x34\xb3\x26\xc3\x09\xa6\x77\xe8\x89\x0f" +
"\xa3\xa0\x81\xbb\xb9\xcf\x69\x13\x7a\x00\xcb\xc0\xa8\x4e\xbe\xae\x95\x60\xe6\x9b\x2e\x87\x7a\xad\x4c\xf8\x78\xf3" +
"\x56\x1b\xb9\x67\x05\x1a\x85\xed\x8c\xf2\x71\xf2\x46\x3c\x6f\x73\x77\x25\xfd\x3a\x2c\x47\xb9\xa9\xce\x28\x85\xcf" +
"\x9a\x08\x9c\x2d\x95\x59\x9e\x55\xc2\x79\xb4\x67\x85\xc9\x1d\xbf\x1e\x86\x20\x8b\x51\x55\xc0\xf7\x5d\x52\xf6\x45" +
"\x39\xd2\xb9\x80\xee\xec\xe5\xff\x3d\xe4\xae\xc9\x45\xc4\xc7\x0e\x3d\x93\xc0\xd4\x35\x76\xe4\x22\x12\x2a\x01\xcd" +
"\xc4\xc9\xf3\xd6\x20\x26\x96\xe0\xbb\x5a\xf2\x27\x8d\xf5\xaa\x65\x3f\x4b\x65\xf2\x7b\x6a\x8e\xd4\xc5\x09\x01\x35" +
"\x4c\xae\x79\x63\x33\x68\xa4\xaf\x8e\xa6\x34\x97\x90\xa0\xfe\xb2\x20\x59\xf2\x25\x59\x1a\x6b\x61\x2b\x1c\x14\xe8" +
"\x31\xe7\xf8\x77\x38\x16\x65\x57\x46\xac\x2c\x03\x01\xd9\xe5\xcd\xdd\x74\x7e\x72\x9a\xb5\xa5\xc7\x85\x75\xc0\xff" +
"\x22\x54\xa7\x62\x15\xed\x4d\xe6\x81\x16\x10\xed\x37\xb6\x7d\x30\xb9\x26\xb5\x5d\x8b\xb1\x42\x9b\x4a\xa8\x5d\x17" +
"\x65\x1f\x19\xc1\x34\x98\x5a\x7c\x0c\x09\x12\x9c\xb7\x21\xa7\x3c\x19\xa4\xeb\xda\x2d\x31\x2a\x6a\x45\xdd\xfb\x5c" +
"\x66\xd3\xf7\xb8\x6b\xa9\xea\x36\xdd\xeb\xa6\xeb\xf5\x3e\xc3\x40\x2f\xa4\x72\xe9\x12\x98\xc0\x8a\x45\x75\xda\x92" +
"\x83\x13\xfc\x34\xea\xf6\xac\x58\xd0\x67\x34\x7f\xd1\x07\x70\x35\x49\x37\x25\x4c\xaf\xe6\x83\xe4\x2b\x26\x51\x65" +
"\x63\x3f\x95\x03\x67\x06\xb9\xa5\xa5\x5b\xe8\xf3\xd1\x69\x67\x02\x20\x9d\x33\xb6\xb4\xeb\x09\x84\xdc\x1a\xd7\x5c" +
"\xae\xf6\xfa\x18\xf3\x69\x9f\xae\x57\xe2\x8d\x1b\x78\xb3\x42\xea\xb8\x2d\xc0\x90\x21\x9f\xab\xf4\x87\x23\xef\x46" +
"\x58\xc9\x07\x31\x67\x90\xda\xa3\xd5\x42\x29\xee\xb9\x04\xfc\x91\xe1\xd3\xd0\xd7\x34\x52\xa3\x87\x85\x74\xf7\x8f" +
"\x20\xaa\x1b\xfd\xe5\x8c\x1e\xc1\xc4\x33\xdd\xab\x88\x23\x38\xd4\x8e\x75\xdf\x5a\x2a\x07\x62\xb2\x71\x8c\x44\x0b" +
"\xc8\xf7\x42\xfb\xc1\x60\x6d\x0c\x7b\xee\xfa\x0f\x0e\x4c\x6d\x71\x93\x2e\x4e\x1b\x22\x41\x42\x1a\xa8\x89\x72\x8c" +
"\x26\xc6\x70\x9f\x2e\xb2\x2a\xb1\x17\x46\x3c\xa0\x12\x7a\xd7\xd3\x90\xcf\x2d\xf9\x2e\xb8\x8b\xc7\xf4\x64\x41\x46" +
"\x7e\x66\x6e\x4d\xf1\x79\x7d\x33\x1b\x4f\xde\x4c\x79\x14\x3d\xe9\xb8\xfa\x14\x66\xe3\xd7\xe3\xd9\x78\x7a\x39\xbe" +
"\xdd\xdf\x68\x9d\xd0\x18\x7b\x9a\x80\xfa\x66\x0a\x57\xe3\xb7\xe3\xf9\x18\x2e\x2f\x6e\x2f\x2f\xae\xc6\xf4\xe4\xee" +
"\x1d\xcd\x75\xcd\x13\x6e\x02\x93\x92\xd2\xb7\x40\x85\x3e\xd2\x18\xce\xcb\x2e\xc9\x79\xea\x8f\x3b\xc9\x0f\x42\xa9" +
"\xc3\x22\x70\xe9\x37\x81\x78\x4a\x41\xf3\xff\x16\x95\x1a\x3d\x62\x63\xea\x1a\x7d\x03\xf9\xa7\xb6\x68\xdd\xe0\x70" +
"\xcf\x49\x77\x72\xea\x6f\xeb\x5c\xb7\x47\xcf\x9c\xfe\xf4\xf9\x1f\x02\xff\x1b\x00\x00\xff\xff\x66\x75\x1e\xc1\xab" +
"\x1c\x00\x00")
func bindataDataMigrations1createmsmtresultssqlBytes() ([]byte, error) {
return bindataRead(

View File

@ -122,6 +122,7 @@ func CreateMeasurement(sess sqlbuilder.Database, m Measurement, i string) (*Meas
// XXX Do we want to have this be part of something else?
m.StartTime = time.Now().UTC()
m.TestKeys = ""
// XXX insert also the URL and stuff
//m.Input = i

View File

@ -0,0 +1,56 @@
package database
import (
"database/sql"
"io/ioutil"
"os"
"testing"
"time"
)
func TestMeasurementWorkflow(t *testing.T) {
tmpfile, err := ioutil.TempFile("", "dbtest")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpfile.Name())
tmpdir, err := ioutil.TempDir("", "oonitest")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpdir)
sess, err := Connect(tmpfile.Name())
if err != nil {
t.Error(err)
}
result, err := CreateResult(sess, tmpdir, Result{
TestGroupName: "websites",
StartTime: time.Now().UTC(),
})
if err != nil {
t.Fatal(err)
}
msmtTemplate := Measurement{
ReportID: sql.NullString{String: "", Valid: false},
TestName: "antani",
ResultID: result.ID,
ReportFilePath: tmpdir,
}
m1, err := CreateMeasurement(sess, msmtTemplate, "")
if err != nil {
t.Fatal(err)
}
var m2 Measurement
err = sess.Collection("measurements").Find("id", m1.ID).One(&m2)
if err != nil {
t.Fatal(err)
}
if m2.ResultID != m1.ResultID {
t.Error("result_id mismatch")
}
}

View File

@ -13,6 +13,8 @@ func TestConnect(t *testing.T) {
if err != nil {
t.Error(err)
}
defer os.Remove(tmpfile.Name())
sess, err := Connect(tmpfile.Name())
if err != nil {
t.Error(err)
@ -27,5 +29,4 @@ func TestConnect(t *testing.T) {
log.Fatal("missing tables")
}
defer os.Remove(tmpfile.Name())
}

View File

@ -1,6 +1,7 @@
package database
import (
"database/sql"
"os"
"path/filepath"
"time"
@ -28,25 +29,26 @@ type URL struct {
// Measurement model
type Measurement struct {
ID int64 `db:"id"`
TestName string `db:"test_name"`
StartTime time.Time `db:"start_time"`
Runtime float64 `db:"runtime"` // Fractional number of seconds
NetworkID int64 `db:"network_id"` // Used to include a Network
IsDone bool `db:"is_done"`
IsUploaded bool `db:"is_uploaded"`
IsFailed string `db:"is_failed"`
FailureMsg string `db:"failure_msg"`
IsUploadFailed bool `db:"is_upload_failed"`
UploadFailureMsg string `db:"upload_failure_msg"`
IsRerun bool `db:"is_rerun"`
ReportID string `db:"report_id"`
URLID string `db:"url_id"` // Used to reference URL
MeasurementID int64 `db:"measurement_id"`
IsAnomaly bool `db:"is_anomaly"`
TestKeys struct{} `db:"test_keys"`
ResultID int64 `db:"result_id"`
ReportFilePath string `db:"report_file_path"`
ID int64 `db:"id"`
TestName string `db:"test_name"`
StartTime time.Time `db:"start_time"`
Runtime float64 `db:"runtime"` // Fractional number of seconds
NetworkID int64 `db:"network_id"` // Used to include a Network
IsDone bool `db:"is_done"`
IsUploaded bool `db:"is_uploaded"`
IsFailed string `db:"is_failed"`
FailureMsg sql.NullString `db:"failure_msg,omitempty"`
IsUploadFailed bool `db:"is_upload_failed"`
UploadFailureMsg sql.NullString `db:"upload_failure_msg,omitempty"`
IsRerun bool `db:"is_rerun"`
ReportID sql.NullString `db:"report_id,omitempty"`
URLID string `db:"url_id"` // Used to reference URL
MeasurementID sql.NullInt64 `db:"measurement_id,omitempty"`
IsAnomaly sql.NullBool `db:"is_anomaly,omitempty"`
// FIXME we likely want to support JSON. See: https://github.com/upper/db/issues/462
TestKeys string `db:"test_keys"`
ResultID int64 `db:"result_id"`
ReportFilePath string `db:"report_file_path"`
}
// Result model
@ -84,7 +86,7 @@ func (m *Measurement) SetGeoIPInfo() error {
// Failed writes the error string to the measurement
func (m *Measurement) Failed(sess sqlbuilder.Database, failure string) error {
m.FailureMsg = failure
m.FailureMsg = sql.NullString{String: failure, Valid: true}
err := sess.Collection("measurements").Find("id", m.ID).Update(m)
if err != nil {
return errors.Wrap(err, "updating measurement")
@ -107,7 +109,7 @@ func (m *Measurement) Done(sess sqlbuilder.Database) error {
// UploadFailed writes the error string for the upload failure to the measurement
func (m *Measurement) UploadFailed(sess sqlbuilder.Database, failure string) error {
m.UploadFailureMsg = failure
m.UploadFailureMsg = sql.NullString{String: failure, Valid: true}
m.IsUploaded = false
err := sess.Collection("measurements").Find("id", m.ID).Update(m)