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 @@ ...@@ -9,6 +9,74 @@
from PyQt5 import QtCore from PyQt5 import QtCore
qt_resource_data = b"\ 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\ \x00\x00\x04\xf7\
\x89\ \x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
...@@ -91,6 +159,69 @@ qt_resource_data = b"\ ...@@ -91,6 +159,69 @@ qt_resource_data = b"\
\xb8\x6b\x82\x11\xef\x6d\x0d\x8d\x21\x40\x49\x13\xd4\x68\x34\xf1\ \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\ \xe6\x1b\x73\x4e\x70\x5b\x16\x15\xc8\x8a\x00\x00\x00\x00\x49\x45\
\x4e\x44\xae\x42\x60\x82\ \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"\ qt_resource_name = b"\
...@@ -98,25 +229,39 @@ qt_resource_name = b"\ ...@@ -98,25 +229,39 @@ qt_resource_name = b"\
\x0a\x6c\x78\x43\ \x0a\x6c\x78\x43\
\x00\x72\ \x00\x72\
\x00\x65\x00\x73\x00\x6f\x00\x75\x00\x72\x00\x63\x00\x65\x00\x73\ \x00\x65\x00\x73\x00\x6f\x00\x75\x00\x72\x00\x63\x00\x65\x00\x73\
\x00\x09\ \x00\x06\
\x03\x83\xa6\xc7\ \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\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"\ 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\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\ \x00\x00\x00\x18\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
" "
qt_resource_struct_v2 = b"\ qt_resource_struct_v2 = 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\x01\
\x00\x00\x00\x00\x00\x00\x00\x00\ \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\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\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(".") qt_version = QtCore.qVersion().split(".")
......
...@@ -39,11 +39,10 @@ from click_plugins import with_plugins ...@@ -39,11 +39,10 @@ from click_plugins import with_plugins
from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QCoreApplication from PyQt5.QtCore import QCoreApplication
from beat.core.dock import Host
from beat.cmdline.click_helper import AliasedGroup from beat.cmdline.click_helper import AliasedGroup
from beat.cmdline.decorators import raise_on_error from beat.cmdline.decorators import raise_on_error
from beat.cmdline.decorators import verbosity_option from beat.cmdline.decorators import verbosity_option
from beat.cmdline import environments
from ..utils import setup_logger from ..utils import setup_logger
from ..utils import check_prefix_folders from ..utils import check_prefix_folders
...@@ -64,19 +63,13 @@ global logger ...@@ -64,19 +63,13 @@ global logger
logger = None 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): def setup_environment_cache(ctx, param, value):
"""Click option callback to setup environment cache""" """Click option callback to setup environment cache"""
if not value: if not value:
environments = ctx.meta["environments"] environments_file_path = ctx.meta["environments"]
if not os.path.exists(environments): if not os.path.exists(environments_file_path):
dump_environments(environments) ctx.invoke(environments.list, type_="all", output=environments_file_path)
def check_prefix(prefix_path): def check_prefix(prefix_path):
...@@ -194,15 +187,22 @@ Example: ...@@ -194,15 +187,22 @@ Example:
@editor.command(epilog=ENV_REFRESH_EPILOG) @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 @click.pass_context
@raise_on_error @raise_on_error
def refresh_env(ctx): def refresh_env(ctx, type_):
"""Update environments cache""" """Update environments cache"""
environments_file_path = ctx.meta["environments"] environments_file_path = ctx.meta["environments"]
if os.path.exists(environments_file_path): if os.path.exists(environments_file_path):
os.remove(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) @editor.group(cls=AliasedGroup)
......
...@@ -94,8 +94,29 @@ def test_prefix(): ...@@ -94,8 +94,29 @@ def test_prefix():
env_file.write( env_file.write(
json.dumps( json.dumps(
{ {
"Test Env": {"name": "Python 2.7", "version": "1.3.0"}, "remote": [
"Another test Env": {"name": "another test", "version": "1.1.1"}, {
"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 ...@@ -27,7 +27,6 @@ import copy
import pytest import pytest
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from PyQt5.QtCore import QStringListModel
from PyQt5.QtWidgets import QComboBox from PyQt5.QtWidgets import QComboBox
from PyQt5.QtWidgets import QCheckBox from PyQt5.QtWidgets import QCheckBox
...@@ -62,6 +61,7 @@ from ..widgets.experimenteditor import typed_user_property ...@@ -62,6 +61,7 @@ from ..widgets.experimenteditor import typed_user_property
from ..widgets.experimenteditor import ExperimentResources from ..widgets.experimenteditor import ExperimentResources
from ..widgets.experimenteditor import AlgorithmResourceModel from ..widgets.experimenteditor import AlgorithmResourceModel
from ..widgets.experimenteditor import QueueResourceModel
from .conftest import prefix from .conftest import prefix
from .conftest import sync_prefix from .conftest import sync_prefix
...@@ -116,6 +116,13 @@ def parameter_choice_map(prefix_path, algorithm_name): ...@@ -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 # Fixtures
...@@ -280,6 +287,40 @@ class TestAlgorithmResourceModel: ...@@ -280,6 +287,40 @@ class TestAlgorithmResourceModel:
assert algorithm_model.rowCount() == query.value("cnt") 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: class TestIOMapperDialog:
"""Test that the dialog used for input/output mapping works as expected""" """Test that the dialog used for input/output mapping works as expected"""
...@@ -506,7 +547,7 @@ class TestEnvironmentModel: ...@@ -506,7 +547,7 @@ class TestEnvironmentModel:
model = EnvironmentModel() model = EnvironmentModel()
model.setContext(beat_context) model.setContext(beat_context)
assert model.rowCount() == 2 assert model.rowCount() == 4
def test_visual_name(self, beat_context): def test_visual_name(self, beat_context):
model = EnvironmentModel() model = EnvironmentModel()
...@@ -728,7 +769,6 @@ class TestExecutionPropertiesEditor(PropertiesEditorTestMixin, ParameterTestMixi ...@@ -728,7 +769,6 @@ class TestExecutionPropertiesEditor(PropertiesEditorTestMixin, ParameterTestMixi
editor = self.editor_klass(test_prefix) editor = self.editor_klass(test_prefix)
editor.setAlgorithmResourceModel(algorithm_model) editor.setAlgorithmResourceModel(algorithm_model)
editor.setEnvironmentModel(environment_model) editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test"]))
return editor return editor
...@@ -745,7 +785,6 @@ class TestBlockEditor(TestExecutionPropertiesEditor): ...@@ -745,7 +785,6 @@ class TestBlockEditor(TestExecutionPropertiesEditor):
editor = self.editor_klass("block_name", test_prefix) editor = self.editor_klass("block_name", test_prefix)
editor.setEnvironmentModel(environment_model) editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test"]))
return editor return editor
...@@ -762,7 +801,6 @@ class TestAnalyzerBlockEditor(PropertiesEditorTestMixin): ...@@ -762,7 +801,6 @@ class TestAnalyzerBlockEditor(PropertiesEditorTestMixin):
editor = self.editor_klass("block_name", test_prefix) editor = self.editor_klass("block_name", test_prefix)
editor.setEnvironmentModel(environment_model) editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test"]))
return editor return editor
...@@ -779,7 +817,6 @@ class TestLoopBlockEditor(TestExecutionPropertiesEditor): ...@@ -779,7 +817,6 @@ class TestLoopBlockEditor(TestExecutionPropertiesEditor):
editor = self.editor_klass("block_name", test_prefix) editor = self.editor_klass("block_name", test_prefix)
editor.setEnvironmentModel(environment_model) editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test"]))
return editor return editor
def test_edit_environment( def test_edit_environment(
...@@ -1023,7 +1060,6 @@ class TestGlobalParametersEditor: ...@@ -1023,7 +1060,6 @@ class TestGlobalParametersEditor:
environment_model = EnvironmentModel() environment_model = EnvironmentModel()
environment_model.setContext(beat_context) environment_model.setContext(beat_context)
editor.setEnvironmentModel(environment_model) editor.setEnvironmentModel(environment_model)
editor.setQueueModel(QStringListModel(["Test", "Test2"]))
return editor return editor
@pytest.mark.parametrize( @pytest.mark.parametrize(
...@@ -1066,13 +1102,15 @@ class TestGlobalParametersEditor: ...@@ -1066,13 +1102,15 @@ class TestGlobalParametersEditor:
def test_change_environment(self, qtbot, gpe_editor, exp_globals): def test_change_environment(self, qtbot, gpe_editor, exp_globals):
gpe_editor.load(exp_globals) gpe_editor.load(exp_globals)
with qtbot.waitSignal(gpe_editor.dataChanged): 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 assert gpe_editor.dump() != exp_globals
def test_change_queue(self, qtbot, gpe_editor, exp_globals): def test_change_queue(self, qtbot, gpe_editor, exp_globals):
gpe_editor.load(exp_globals) gpe_editor.load(exp_globals)
with qtbot.waitSignal(gpe_editor.dataChanged): 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 assert gpe_editor.dump() != exp_globals
...@@ -1190,8 +1228,10 @@ class TestExperimentEditor: ...@@ -1190,8 +1228,10 @@ class TestExperimentEditor:
block_editor = list_widget.widget_list[0] block_editor = list_widget.widget_list[0]
properties_editor = block_editor.properties_editor properties_editor = block_editor.properties_editor
combobox = properties_editor.environment_combobox combobox = properties_editor.environment_combobox
with qtbot.waitSignal(experiment_editor.dataChanged): with qtbot.waitSignal(experiment_editor.dataChanged):
combobox.setCurrentIndex(1) index = combobox.currentIndex()
combobox.setCurrentIndex(change_index(index))
dump = experiment_editor.dump_json() dump = experiment_editor.dump_json()
assert dump != experiment_declaration assert dump != experiment_declaration
......
...@@ -117,7 +117,7 @@ class EnvironmentModel(QStandardItemModel): ...@@ -117,7 +117,7 @@ class EnvironmentModel(QStandardItemModel):
"""Model wrapping the processing environment available""" """Model wrapping the processing environment available"""
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(3, 0, parent) super().__init__(4, 0, parent)
self.context = None self.context = None
...@@ -125,19 +125,30 @@ class EnvironmentModel(QStandardItemModel): ...@@ -125,19 +125,30 @@ class EnvironmentModel(QStandardItemModel):
def refreshContent(self): def refreshContent(self):
self.clear() self.clear()
if self.context is not None: if self.context is not None:
with open(self.context.meta["environments"], "rt") as file_:
json_data = json.load(file_) def add_row(type_, data):
for docker_name, data in json_data.items():
if "databases" not in data:
visual_name = "{name} ({version})".format(**data) visual_name = "{name} ({version})".format(**data)
icon = QIcon(f":/resources/{type_}")
self.appendRow( self.appendRow(
[ [
QStandardItem(visual_name), QStandardItem(icon, visual_name),
QStandardItem(data["name"]), QStandardItem(data["name"]),
QStandardItem(data["version"]), 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): def setContext(self, context):
self.context = context self.context = context
self.refreshContent() self.refreshContent()
...@@ -159,6 +170,14 @@ class EnvironmentModel(QStandardItemModel): ...@@ -159,6 +170,14 @@ class EnvironmentModel(QStandardItemModel):
version = self.data(version) version = self.data(version)
return {"name": name, "version": 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): class ContainerWidget(ScrollWidget):
"""Container widget to show block editors""" """Container widget to show block editors"""
...@@ -225,6 +244,8 @@ class DatasetModel(QStringListModel): ...@@ -225,6 +244,8 @@ class DatasetModel(QStringListModel):
class ExperimentResources: class ExperimentResources:
"""Modelization of the experiments resources"""
def __init__(self, context=None): def __init__(self, context=None):
self.context = context