Commit 0d6ff0f9 authored by Flavio TARSETTI's avatar Flavio TARSETTI

Merge branch '185_experience_environment_improvement' into 'master'

Experience environment improvement

See merge request !113
parents 52a19134 50dfd546
Pipeline #35611 passed with stages
in 14 minutes and 46 seconds
......@@ -9,6 +9,74 @@
from PyQt5 import QtCore
qt_resource_data = b"\
\x00\x00\x04\x1d\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x32\x00\x00\x00\x32\x08\x06\x00\x00\x00\x1e\x3f\x88\xb1\
\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\
\xa7\x93\x00\x00\x03\xd2\x49\x44\x41\x54\x68\x81\xed\xd9\x4f\x8c\
\x5d\x53\x1c\x07\xf0\x8f\x19\xa6\x33\x46\xa9\x54\x2a\x98\x41\x54\
\x4a\xea\x4f\x2c\x2a\x46\x08\xd1\x84\x54\x68\x17\x22\x12\x2c\x4a\
\x24\x36\x22\x11\x0d\x0b\x6c\x1a\x0b\x12\x06\x1b\xa5\x16\xe2\xdf\
\x4c\x11\x2b\x52\x2c\x58\x35\x61\xd1\x8c\x88\x96\xd4\x9f\x4d\x27\
\x99\xa2\x69\xa2\x2a\x35\xda\x0c\xcf\xe2\x9c\xdb\xf3\x3a\xf3\xde\
\xcc\xbd\xf7\xdd\xf7\xde\xe6\x7d\x93\x9b\xcc\x3b\xf7\xfb\xfb\x77\
\xef\xfd\xfd\x39\x67\xe8\xa1\x87\x1e\x7a\xe8\xa1\x87\xf2\x38\xa5\
\x03\x36\xc6\x70\x17\xae\xc3\x1a\xac\xc0\xbf\x98\xc1\x01\x7c\x81\
\x8f\xb1\xa7\x03\xbe\x94\xc2\x46\x7c\x87\x5a\xce\xeb\x2b\xdc\xdc\
\x15\x4f\x9b\xe0\x2c\xbc\x2f\x39\xf8\x1b\x5e\xc4\x1d\xb8\x00\x43\
\x18\x16\xde\xce\x46\x6c\xc7\xc1\x3a\xfe\x7b\x91\xd3\x55\xac\xc2\
\xb7\x82\x43\x7f\xe2\x71\x0c\xe4\x90\x1b\xc6\xd3\x38\x12\x65\x77\
\xe3\xbc\x36\xf9\xb8\x24\x06\x31\x15\x1d\xf9\x41\x78\xe2\x45\xb1\
\x16\x3f\x4b\xc1\x74\xe5\xcd\x6c\x8b\x0e\xfc\x82\x73\x5b\xd0\x73\
\x8e\x14\xcc\xbb\x15\xf8\xb5\x00\xeb\xf0\x36\xf6\xe3\x1f\x4c\x0b\
\x15\x67\x33\xae\x17\x2a\xd1\x31\x5c\x5d\x81\xad\xb5\xf8\x4b\x08\
\xe6\xa6\x0a\xf4\x21\x94\xe8\xe7\xf1\x9f\xe6\x15\x27\xbb\xf7\x5c\
\x55\x46\xf1\x8c\x54\xcd\x2a\xc1\xb3\x51\xe1\x71\xbc\x80\xcb\x71\
\x9a\x90\xd8\xf7\x48\xc9\x3d\x1b\xd7\xaa\xc2\xb0\x54\xcd\xae\x6c\
\x55\xd9\x15\x98\x13\x3e\x9b\x4d\x4d\x38\xcb\xf0\x21\x26\x5a\x35\
\xd6\x00\x6f\x08\x81\x3c\xd5\xaa\xa2\x57\xa3\xa2\xd7\x97\xe0\x9d\
\x8a\x4b\x5a\x35\xd6\x00\x9b\xa2\xfd\x2f\x5b\x55\xf4\x53\x54\xb4\
\xae\x55\x45\x25\xb1\x26\xda\xff\xb1\xac\x82\x3e\x6c\x10\xf2\xa2\
\x26\xf4\x88\x6e\x60\x79\xb4\x7f\xa4\x8c\xf0\x06\xec\x73\x72\x55\
\xea\xab\xcc\xb5\x62\x18\x92\xaa\xe2\x9d\x38\x3b\x8f\x50\x3f\x5e\
\x92\x9c\xdf\x8f\xad\xb8\xac\x3d\x3e\xe6\xc2\xf9\x4e\x7e\xa0\xc7\
\xf0\x26\x2e\x5c\x4c\x68\x5b\x1d\x79\x8b\x90\xc0\xdd\xc6\x2a\xa1\
\x87\xbd\x22\x24\xfc\x9c\xe0\xe3\x61\xdc\xdd\x48\xe0\x3e\xa9\x17\
\xac\xef\x8c\x8f\xa5\x30\x8a\x8f\x04\x5f\xe7\x70\x7f\xfd\xcd\x41\
\x61\x83\x53\xc3\x43\x25\x0d\x9c\x29\x0c\x79\xbb\x1a\xdc\xdb\xb5\
\xc8\xfa\xee\x28\x5b\x14\x59\xd7\x9f\x55\x37\x12\xdd\x1b\x17\xbf\
\x51\x2e\xa9\xfb\xb1\x33\xea\x98\x6a\x70\x3f\xfb\xbe\xe7\x23\x9b\
\x94\x77\x46\x1d\x45\xb1\x3d\xca\x7f\x9d\x2d\x4c\xc4\x85\xc7\x4a\
\x28\x83\xf1\x28\x7f\x08\x97\x36\xb8\xdf\x2c\x90\x8b\xf1\x7b\xbc\
\x37\x5e\xc2\xee\x72\x69\x84\x59\x4f\x6a\x7a\x57\x95\x50\xf6\x80\
\x34\x87\xdd\xd2\x84\xd3\x2c\x10\xb8\x51\x98\xa4\x6b\x78\xb8\x84\
\xfd\xad\x51\xf6\x35\xc2\x4e\xae\x86\x95\x05\x95\x8c\x09\x15\x6e\
\xa9\xdc\x5a\x2c\x10\x51\x36\xab\x96\x63\x05\x7d\xb8\x36\xca\x7e\
\x4f\x7a\x22\xcb\x0a\x28\x18\x90\x36\x3f\x2f\x2f\xc1\x5d\x2a\x10\
\x51\x47\x4d\xf8\x3a\xf2\x6c\x8d\x33\xac\x90\xca\xb1\xe9\xf8\x63\
\xd1\x26\x33\x0f\x0f\x46\x99\x3d\x39\x0c\xe7\x09\x64\x00\x7b\x23\
\x6f\x73\x01\x3f\x06\xa3\xcc\x6c\x9f\x30\x8e\xc0\x0d\x05\x14\x64\
\xcd\x68\x5c\xc8\x8f\x56\x71\x5c\x98\x2a\xea\x75\xe7\x41\x36\x71\
\x1f\x80\x47\x85\xa8\x3e\x2b\xa0\x20\xab\x36\x23\x39\xb8\x79\xde\
\x08\xa1\xd9\xd5\xf0\x6b\x01\x3f\xb6\x44\x99\x49\x42\x92\x1f\x8e\
\x0b\xb7\xe6\x54\x90\x8d\x0a\x79\xea\x7f\xde\x40\xfa\xa5\x8e\x9d\
\x07\x43\xc2\x3c\x58\x13\xce\xc7\xc0\x93\x71\xe1\x20\x56\x57\xe8\
\x5c\xbb\xb8\xfd\xf8\x40\x6a\xc2\x27\x1a\x79\x1f\x3e\x91\x82\xb9\
\xad\x0b\xce\xe5\xe5\x9e\x8e\x77\x22\xef\x28\xae\x99\x4f\x38\x43\
\x0a\xa6\x86\xcf\x85\x61\xf2\x22\x0b\x2b\x53\xa7\x03\x19\x12\x0e\
\x20\x9e\x90\xaa\xec\x51\xdc\xde\x4c\x51\x5f\x24\xff\x51\xa7\xb4\
\xfe\xaa\xd2\xb9\x3c\xdc\x66\xc7\x4f\x53\x72\x9e\x9f\xad\xc4\x23\
\xc2\x5b\x99\x96\x3a\x78\x15\xce\x15\xe1\x66\xbf\xff\x16\x4e\x30\
\xdf\x12\x76\x8a\x95\xfd\x3b\xa4\xdb\xc9\xbe\x00\xdd\xda\x8b\x57\
\x8e\xa2\x81\x8c\x60\x47\xdd\xef\x49\xcd\x9b\x62\xbb\xb8\x2d\x63\
\x54\xd8\x73\xcc\x4f\xbc\x43\x0d\x8c\xb6\x8b\x5b\x09\x76\x44\x03\
\x9f\x46\x03\x23\xf1\xef\x13\x23\x42\x07\xb8\x95\x60\x26\x2a\x1f\
\xad\x5b\xcb\xe6\xa3\x99\x0e\x71\x9b\xa2\x4c\xb2\x17\xa9\x2a\xed\
\xe2\xb6\x84\x49\xe9\x13\x18\x8d\x57\xf6\x09\xcc\x3f\x89\x6f\x17\
\xb7\x12\x8c\xc8\x9f\x94\xed\xe2\x56\x86\x11\xe1\x09\xce\xc4\x6b\
\x62\x11\x63\xed\xe2\x36\xc4\xff\xef\xb3\x8d\xc1\x9b\x2f\xa4\x85\
\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x04\xf7\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
......@@ -91,6 +159,69 @@ qt_resource_data = b"\
\xb8\x6b\x82\x11\xef\x6d\x0d\x8d\x21\x40\x49\x13\xd4\x68\x34\xf1\
\xe6\x1b\x73\x4e\x70\x5b\x16\x15\xc8\x8a\x00\x00\x00\x00\x49\x45\
\x4e\x44\xae\x42\x60\x82\
\x00\x00\x03\xc7\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
\x00\x00\x32\x00\x00\x00\x32\x08\x06\x00\x00\x00\x1e\x3f\x88\xb1\
\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\
\xa7\x93\x00\x00\x03\x7c\x49\x44\x41\x54\x68\x81\xed\xd8\x6f\x88\
\xe5\x63\x14\x07\xf0\xcf\x1d\xeb\xcf\x5a\x22\xb5\xc3\x0e\xb1\x9b\
\x55\xa3\x86\x32\xc5\x48\x76\x15\xde\x58\xe3\x05\xda\x57\xf2\x6a\
\xc3\x2b\x2b\x4a\xde\x08\x25\x94\xb4\x65\xa3\x94\xb6\x36\x14\x9b\
\x52\xd6\x9f\x24\x49\x44\xad\x06\xbb\x78\xa1\x76\xb3\x8c\xdd\xb5\
\xda\x64\xe9\x9a\xd6\x8c\x71\xbd\x38\xcf\x9d\xfb\x73\xdd\xdf\xbd\
\x73\xe7\xde\xdf\xb5\xe9\xf7\xad\xa7\x7b\x7f\xe7\x39\xcf\xf9\xf3\
\x3b\xcf\x73\xce\x79\x7e\x94\x28\x51\xa2\x44\x89\x12\x25\x54\x0a\
\x90\x59\x1b\xb0\x3e\x30\x54\x94\xe0\x41\x63\x59\x81\xb2\xb3\x6f\
\xbf\x5d\x94\xfa\x82\xff\x4d\x44\x8e\x67\x47\x86\x71\x56\x11\x82\
\x6b\x7d\x18\x8b\xc5\x18\x8e\xe2\x67\x5c\xdf\x1f\xf3\x1b\x18\x94\
\x23\x15\x7c\x9e\x59\xf3\x07\x36\xf4\xcb\x09\x39\xc6\xf4\x42\xcb\
\xc3\xba\xc4\xfb\x3d\xb6\xa4\xff\x47\x70\x6e\x37\xc6\xb6\xc3\xa0\
\x1c\x79\x26\xf1\x3e\x22\xa2\xb3\x33\x3d\xef\xec\xc2\xd6\xb6\x18\
\x94\x23\x1f\x24\xde\x6b\xd3\xf3\x4a\x54\xf1\x17\x46\xb1\x02\xa7\
\x36\x2f\xca\xcb\x5a\xed\xf6\x77\xbf\x68\x79\xce\x9d\x92\x7e\xab\
\xe9\xf7\x08\x76\x88\xe8\xec\x49\xf4\xdf\xf1\x13\x5e\xc1\xfa\x1c\
\x1f\x72\x15\x16\x35\x9a\xf1\x46\xa2\xdf\x92\xa1\xdd\x98\xe1\xaf\
\x62\xa6\x49\xc6\x8b\x9d\x1c\x19\x34\x0d\x1e\x4e\xf4\xad\x4d\xf4\
\x31\x8c\x64\x9e\xd7\xe0\xe5\xc4\x7b\xa8\x85\x9c\x81\x19\x9d\xe7\
\xc8\x98\x38\x0f\x33\x38\x2f\xcf\x40\x71\x5e\x0e\x25\x19\xf7\xe7\
\x31\x0d\xd2\x91\x21\x9c\x83\x71\xdc\x8b\xa9\xcc\x5c\xab\xfa\xb1\
\x0a\x0f\xe2\xb7\xc4\xf3\xae\xd4\x33\xbe\x90\x59\x78\xbc\x8c\x83\
\xd8\x24\x0e\xf8\xc5\x78\x13\x9f\x62\x5f\x13\xdf\x4b\x22\x8b\xa1\
\x11\x9e\xff\x6a\xcc\x27\x1b\x76\x63\x3b\x36\x6a\x64\x2e\x78\xad\
\x89\xff\x68\xa2\xad\x6b\x0e\xd5\xb1\xc4\x70\x92\x02\x2f\x3e\x4b\
\xc4\x5a\xfc\x29\x6c\x5c\x8f\x8b\x70\x42\x9a\xfb\x97\xad\xbf\x08\
\x47\x2e\x10\x59\x60\xa4\x99\x21\x2d\xba\x09\x13\x1d\x14\xaf\x16\
\xe1\xbe\x2e\x67\xbe\x82\xdb\xf0\xac\x28\x74\xed\x30\x89\x77\x92\
\x6d\xcf\x37\xcd\x8d\x26\x3d\x0b\xf7\xa9\x0a\xbe\x15\xa9\x6c\x1a\
\xe7\x63\x16\xbb\xf0\x0d\xe6\xc4\x41\x9c\x10\xbd\xce\x3c\x3e\xc1\
\x67\x38\x9c\x64\x2c\x4f\xeb\xc6\x71\x89\x46\x91\xfd\x02\x1f\xe1\
\x87\xa4\x70\x75\x72\x70\x6d\x9a\x9f\x15\xcd\xe1\x1e\x71\x26\x66\
\xd3\xda\x55\xb8\x1a\x97\x25\xbe\x9a\xa8\x2d\x07\xc4\x96\xbb\x34\
\xe9\x1a\x12\x89\x61\xab\x38\xf0\x5e\x4f\xcc\xb7\x77\x78\x43\x83\
\xc4\x32\xf1\x22\x6a\x78\x62\xb1\x8b\x36\xa7\x05\xdb\x8b\xb1\x69\
\x49\x78\x4c\xd8\xb4\x4f\x8b\xbe\x2a\x0f\xa3\x1a\xd9\xe0\xf4\x2e\
\x15\x7e\x8c\xbb\xbb\x5c\xd3\x09\x93\x62\x0b\xcf\x69\x91\x99\x3a\
\xe1\x3d\xe1\xcc\x7d\x8b\xe0\x5d\x29\xce\x14\x71\x06\x3e\xec\x56\
\x59\x1b\x4c\x88\x5e\xaa\x86\x07\xba\x59\x58\x4f\x61\x37\xe0\xed\
\x24\xe4\x51\xec\x17\xd9\x6c\x05\xce\x4e\xe3\x42\x5c\x2e\x22\x38\
\x2f\x9c\x39\xd8\xbb\xed\x0b\xb8\x0a\x6f\xe1\x4c\x6c\xc3\x1d\x5a\
\xb7\x30\x6d\x51\xc1\x8f\x16\x57\xc0\x66\xf0\x2a\x4e\xee\xdd\xf6\
\x05\x6c\xd4\x88\xc4\x0e\x4b\xf8\x4c\x95\x2d\x2a\x57\xe2\x7d\x91\
\x4e\xbf\x12\x8e\x1d\x13\x7d\xff\x61\x51\x7d\xa7\x44\xba\x9c\xeb\
\xc5\xea\x0c\x96\xe3\x71\xdc\x93\x6c\xd9\x86\xbb\x44\xc4\x7b\xc2\
\xcd\x49\x48\x0d\x0f\x29\xae\xd2\x57\x70\xab\xa8\x55\x35\x51\x43\
\x36\xf7\x5b\xc9\x26\xd1\x16\xd4\x0b\x51\xdf\x2e\xfd\xa2\x88\x4d\
\xfa\xe7\x57\x92\xaf\x45\x81\x2b\x04\x1b\x34\x5a\x97\x2a\x9e\xd4\
\xc8\x54\xdd\xa2\x22\xb6\xed\x16\x51\xe5\xeb\x0e\x4c\xe3\x4e\x9c\
\xd8\xab\xb1\x75\x25\x79\x18\xc1\xd3\x62\x0b\x54\x92\xf2\x5d\x22\
\x55\x4f\x61\xaf\x38\x47\x55\xd1\xc8\x9d\x91\x19\x6b\x44\x8b\x51\
\x1f\xc3\x19\xb9\xfb\x93\xdc\xe7\xc4\x37\xab\x81\x61\x5c\xdc\x59\
\xea\x59\x65\x29\x63\x1a\x4f\xe1\x8a\xa2\x8c\xec\xe6\x30\x9f\x86\
\x6b\x44\x3b\x3d\x26\xea\xca\x70\xa2\xcf\xe3\xd7\xcc\x38\x80\x2f\
\xc5\x1d\x63\x37\xbe\xeb\x9b\xc5\x25\x4a\x94\x28\x51\xa2\x44\x01\
\xf8\x1b\xcf\xcc\xb2\x31\xb8\x23\x08\xf2\x00\x00\x00\x00\x49\x45\
\x4e\x44\xae\x42\x60\x82\
"
qt_resource_name = b"\
......@@ -98,25 +229,39 @@ qt_resource_name = b"\
\x0a\x6c\x78\x43\
\x00\x72\
\x00\x65\x00\x73\x00\x6f\x00\x75\x00\x72\x00\x63\x00\x65\x00\x73\
\x00\x09\
\x03\x83\xa6\xc7\
\x00\x06\
\x07\x8c\x46\xa5\
\x00\x72\
\x00\x65\x00\x6d\x00\x6f\x00\x74\x00\x65\
\x00\x05\
\x00\x78\xc3\x80\
\x00\x72\
\x00\x65\x00\x6d\x00\x61\x00\x70\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x65\x00\x6d\x00\x61\x00\x70\
\x00\x06\
\x06\xb5\xa1\xc2\
\x00\x64\
\x00\x6f\x00\x63\x00\x6b\x00\x65\x00\x72\
"
qt_resource_struct_v1 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\
\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x01\x00\x00\x04\x21\
\x00\x00\x00\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x09\x1c\
\x00\x00\x00\x18\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
"
qt_resource_struct_v2 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x01\x00\x00\x04\x21\
\x00\x00\x01\x6d\xa6\x6c\x57\x86\
\x00\x00\x00\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x09\x1c\
\x00\x00\x01\x6d\xb4\x9a\xc2\x77\
\x00\x00\x00\x18\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01\x6c\xb3\xa2\x85\xe8\
\x00\x00\x01\x6d\xb4\xa3\xeb\xbf\
"
qt_version = QtCore.qVersion().split(".")
......
......@@ -39,11 +39,10 @@ from click_plugins import with_plugins
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QCoreApplication
from beat.core.dock import Host
from beat.cmdline.click_helper import AliasedGroup
from beat.cmdline.decorators import raise_on_error
from beat.cmdline.decorators import verbosity_option
from beat.cmdline import environments
from ..utils import setup_logger
from ..utils import check_prefix_folders
......@@ -64,19 +63,13 @@ global logger
logger = None
def dump_environments(environments_file_path):
logger.info("Generating environments information")
Host(images_cache=environments_file_path, raise_on_errors=False)
logger.info("Done")
def setup_environment_cache(ctx, param, value):
"""Click option callback to setup environment cache"""
if not value:
environments = ctx.meta["environments"]
if not os.path.exists(environments):
dump_environments(environments)
environments_file_path = ctx.meta["environments"]
if not os.path.exists(environments_file_path):
ctx.invoke(environments.list, type_="all", output=environments_file_path)
def check_prefix(prefix_path):
......@@ -194,15 +187,22 @@ Example:
@editor.command(epilog=ENV_REFRESH_EPILOG)
@click.option(
"--type",
"-t",
"type_",
type=click.Choice(["docker", "remote", "all"], case_sensitive=False),
default="all",
)
@click.pass_context
@raise_on_error
def refresh_env(ctx):
def refresh_env(ctx, type_):
"""Update environments cache"""
environments_file_path = ctx.meta["environments"]
if os.path.exists(environments_file_path):
os.remove(environments_file_path)
dump_environments(environments_file_path)
ctx.invoke(environments.list, type_=type_, output=environments_file_path)
@editor.group(cls=AliasedGroup)
......
......@@ -94,8 +94,29 @@ def test_prefix():
env_file.write(
json.dumps(
{
"Test Env": {"name": "Python 2.7", "version": "1.3.0"},
"Another test Env": {"name": "another test", "version": "1.1.1"},
"remote": [
{
"name": "Python 2.7",
"version": "1.3.0",
"queues": {"queue1": {}, "queue2": {}},
},
{
"name": "Python",
"version": "2.0.0",
"queues": {
"queue_extra_long": {},
"queue_long": {},
"queue_short": {},
},
},
],
"docker": {
"Docker test env": {"name": "Pytorch", "version": "1.1.1"},
"Second Docker test env": {
"name": "Pytorch 1.0",
"version": "2.1.1",
},
},
}
)
)
......
......@@ -27,7 +27,6 @@ import copy
import pytest
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QStringListModel
from PyQt5.QtWidgets import QComboBox
from PyQt5.QtWidgets import QCheckBox
......@@ -62,6 +61,7 @@ from ..widgets.experimenteditor import typed_user_property
from ..widgets.experimenteditor import ExperimentResources
from ..widgets.experimenteditor import AlgorithmResourceModel
from ..widgets.experimenteditor import QueueResourceModel
from .conftest import prefix
from .conftest import sync_prefix
......@@ -116,6 +116,13 @@ def parameter_choice_map(prefix_path, algorithm_name):
}
def change_index(index):
if index > 0:
return index - 1
else:
return index + 1
# ------------------------------------------------------------------------------
# Fixtures
......@@ -280,6 +287,40 @@ class TestAlgorithmResourceModel:
assert algorithm_model.rowCount() == query.value("cnt")
class TestQueueResourceModel:
"""Test the model used to generate suitable algorithm selections"""
@pytest.fixture
def prefix_model(self, beat_context):
return ExperimentResources(beat_context)
def test_default(self, prefix_model):
model = QueueResourceModel()
query = QSqlQuery()
assert query.exec_("SELECT COUNT(name) AS cnt FROM queues")
query.next()
assert model.rowCount() > 0
assert model.rowCount() == query.value("cnt")
def test_types(self, prefix_model):
model = QueueResourceModel()
for type_ in ["remote", "docker"]:
model.setType(type_)
query = QSqlQuery()
assert query.exec_(
f"SELECT COUNT(name) AS cnt FROM queues WHERE env_type='{type_}'"
)
query.next()
assert model.rowCount() > 0
assert model.rowCount() == query.value("cnt")
class TestIOMapperDialog:
"""Test that the dialog used for input/output mapping works as expected"""
......@@ -506,7 +547,7 @@ class TestEnvironmentModel:
model = EnvironmentModel()
model.setContext(beat_context)
assert model.rowCount() == 2
assert model.rowCount() == 4
def test_visual_name(self, beat_context):
model = EnvironmentModel()
......@@ -728,7 +769,6 @@ class TestExecutionPropertiesEditor(PropertiesEditorTestMixin, ParameterTestMixi
editor = self.editor_klass(test_prefix)
editor.setAlgorithmResourceModel(algorithm_model)
editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test"]))
return editor
......@@ -745,7 +785,6 @@ class TestBlockEditor(TestExecutionPropertiesEditor):
editor = self.editor_klass("block_name", test_prefix)
editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test"]))
return editor
......@@ -762,7 +801,6 @@ class TestAnalyzerBlockEditor(PropertiesEditorTestMixin):
editor = self.editor_klass("block_name", test_prefix)
editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test"]))
return editor
......@@ -779,7 +817,6 @@ class TestLoopBlockEditor(TestExecutionPropertiesEditor):
editor = self.editor_klass("block_name", test_prefix)
editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test"]))
return editor
def test_edit_environment(
......@@ -1023,7 +1060,6 @@ class TestGlobalParametersEditor:
environment_model = EnvironmentModel()
environment_model.setContext(beat_context)
editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test", "Test2"]))
return editor
@pytest.mark.parametrize(
......@@ -1066,13 +1102,15 @@ class TestGlobalParametersEditor:
def test_change_environment(self, qtbot, gpe_editor, exp_globals):
gpe_editor.load(exp_globals)
with qtbot.waitSignal(gpe_editor.dataChanged):
gpe_editor.environment_combobox.setCurrentIndex(1)
index = gpe_editor.environment_combobox.currentIndex()
gpe_editor.environment_combobox.setCurrentIndex(change_index(index))
assert gpe_editor.dump() != exp_globals
def test_change_queue(self, qtbot, gpe_editor, exp_globals):
gpe_editor.load(exp_globals)
with qtbot.waitSignal(gpe_editor.dataChanged):
gpe_editor.queue_combobox.setCurrentIndex(1)
index = gpe_editor.queue_combobox.currentIndex()
gpe_editor.queue_combobox.setCurrentIndex(change_index(index))
assert gpe_editor.dump() != exp_globals
......@@ -1190,8 +1228,10 @@ class TestExperimentEditor:
block_editor = list_widget.widget_list[0]
properties_editor = block_editor.properties_editor
combobox = properties_editor.environment_combobox
with qtbot.waitSignal(experiment_editor.dataChanged):
combobox.setCurrentIndex(1)
index = combobox.currentIndex()
combobox.setCurrentIndex(change_index(index))
dump = experiment_editor.dump_json()
assert dump != experiment_declaration
......
......@@ -117,7 +117,7 @@ class EnvironmentModel(QStandardItemModel):
"""Model wrapping the processing environment available"""
def __init__(self, parent=None):
super().__init__(3, 0, parent)
super().__init__(4, 0, parent)
self.context = None
......@@ -125,19 +125,30 @@ class EnvironmentModel(QStandardItemModel):
def refreshContent(self):
self.clear()
if self.context is not None:
with open(self.context.meta["environments"], "rt") as file_:
json_data = json.load(file_)
for docker_name, data in json_data.items():
if "databases" not in data:
def add_row(type_, data):
visual_name = "{name} ({version})".format(**data)
icon = QIcon(f":/resources/{type_}")
self.appendRow(
[
QStandardItem(visual_name),
QStandardItem(icon, visual_name),
QStandardItem(data["name"]),
QStandardItem(data["version"]),
QStandardItem(type_),
]
)
with open(self.context.meta["environments"], "rt") as file_:
json_data = json.load(file_)
remote_data = json_data.get("remote", {})
for data in remote_data:
add_row("remote", data)
docker_data = json_data.get("docker", {})
for _, data in docker_data.items():
if "databases" not in data:
add_row("docker", data)
def setContext(self, context):
self.context = context
self.refreshContent()
......@@ -159,6 +170,14 @@ class EnvironmentModel(QStandardItemModel):
version = self.data(version)
return {"name": name, "version": version}
def environmentType(self, index):
if is_Qt_equal_or_higher("5.11"):
type_ = index.siblingAtColumn(3)
else:
type_ = index.sibling(index.row(), 3)
return self.data(type_)
class ContainerWidget(ScrollWidget):
"""Container widget to show block editors"""
......@@ -225,6 +244,8 @@ class DatasetModel(QStringListModel):
class ExperimentResources:
"""Modelization of the experiments resources"""
def __init__(self, context=None):
self.context = context
......@@ -246,20 +267,27 @@ class ExperimentResources:
self.refresh()
def refresh(self):
if self.context is None:
return
ALGORITHM_TABLE_CLEANUP = "DROP TABLE IF EXISTS algorithms"
ALGORITHM_TABLE = "CREATE TABLE algorithms(name varchar, type varchar, inputs integer, outputs integer, is_analyzer boolean)"
INSERT_ALGORITHM = "INSERT INTO algorithms(name, type, inputs, outputs, is_analyzer) VALUES(?, ?, ?, ?, ?)"
QUEUE_TABLE_CLEANUP = "DROP TABLE IF EXISTS queues"
QUEUE_TABLE = "CREATE TABLE queues(name varchar, env_name varchar, env_version varchar, env_type varchar)"
INSERT_QUEUE = "INSERT INTO queues(name, env_name, env_version, env_type) VALUES (?, ?, ?, ?)"
query = QSqlQuery()
if not query.exec_(ALGORITHM_TABLE_CLEANUP):
for query_str in [ALGORITHM_TABLE_CLEANUP, QUEUE_TABLE_CLEANUP]:
if not query.exec_(query_str):
raise RuntimeError(f"Failed to drop table: {query.lastError().text()}")
if not query.exec_(ALGORITHM_TABLE):
raise RuntimeError(f"Failed to create table: {query.lastError().text()}")
for query_str in [ALGORITHM_TABLE, QUEUE_TABLE]:
if not query.exec_(query_str):
raise RuntimeError(
f"Failed to create table: {query.lastError().text()}"
)
if self.context is None:
return
prefix_path = self.context.meta["config"].path
model = AssetModel()
......@@ -294,6 +322,40 @@ class ExperimentResources:
f"Failed to insert algorithm: {query.lastError().text()}"
)
if not query.prepare(INSERT_QUEUE):
raise RuntimeError(f"Failed to prepare query: {query.lastError().text()}")
environments_path = self.context.meta["environments"]
with open(environments_path, "rt") as file:
environment_data = json.load(file)
for item in environment_data.get("remote", []):
env_name = item["name"]
env_version = item["version"]
# import ipdb; ipdb.set_trace()
for name in item["queues"].keys():
query.addBindValue(name)
query.addBindValue(env_name)
query.addBindValue(env_version)
query.addBindValue("remote")
if not query.exec_():
raise RuntimeError(
f"Failed to insert queue: {query.lastError().text()}"
)
for _, image_info in environment_data.get("docker", {}).items():
env_name = image_info["name"]
env_version = image_info["version"]
query.addBindValue("Local")
query.addBindValue(env_name)
query.addBindValue(env_version)
query.addBindValue("docker")
if not query.exec_():
raise RuntimeError(
f"Failed to insert queue: {query.lastError().text()}"
)
class AlgorithmResourceModel(QSqlTableModel):
def __init__(self, parent=None):
......@@ -351,6 +413,56 @@ class AlgorithmResourceModel(QSqlTableModel):
self.update()
class QueueResourceModel(QSqlTableModel):
def __init__(self, parent=None):
super().__init__(parent=parent)
self._environment = None
self._version = None
self._type = None
self.setTable("queues")
self.select()
self.update()
def update(self):
filter_str = ""
if self._environment is not None:
filter_str += f"env_name='{self._environment}'"
if self._version is not None:
if filter_str:
filter_str += " AND "
filter_str += f"env_version='{self._version}'"
if self._type is not None:
if filter_str:
filter_str += " AND "
filter_str += f"env_type='{self._type}'"
self.setFilter(filter_str)
def setEnvironment(self, name, version):
if self._environment == name and self._version == version:
return
self._environment = name
self._version = version
self.update()
def setType(self, type_):
if self._type == type_:
return
self._type = type_
self.update()
def dump(self):
print(self.filter())
for i in range(self.rowCount()):
print([self.index(i, j).data() for j in range(4)])
# ------------------------------------------------------------------------------
# Editors
......@@ -673,14 +785,16 @@ class ExecutionPropertiesEditor(AbstractBaseEditor):
self._queue_enabled = True
self.parameter_item = None
self.algorithm_model = None
self.queue_model = QueueResourceModel()
self.algorithm_combobox = QComboBox()