Wednesday, 27 May 2020

TAO - Assesment Platform

Panduan pertanyaan : 
  1. Bagaimana cara membuat item test secara programatik ? Solved
  2. Bagaimana cara membuat QTI/APIP Test Content Package secara programatik ? Solved
Bump!


Versioning Custom Fork

Untuk  versioning nama rilis, penilasannya kita menggunakan tambahan 1 digit increment dibelakkang versi rilis resmi dari upstream-nya, contoh, untuk v2.24.1  tao-test-runner-qti-fe maka setiap kali melakukan perubahan kita akan menggunakan nama rilis v2.24.1.1, v2.24.1.2, dst-nya 

Config Git 

git config --global url."https://github".insteadOf git://github

Intalasi 

Official Docker Install

docker run -ti --name taotesting-core -p 8080:80 taotesting/core:latest

Debian

sudo apt update

sudo apt install -y curl wget gnupg2 ca-certificates lsb-release apt-transport-https

wget https://packages.sury.org/php/apt.gpg

sudo apt-key add apt.gpg

echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php7.list

sudo apt update

sudo apt install nginx php7.4 php7.4-fpm php7.4-cli php7.4-common mariadb-server mariadb-client php7.4-xml php7.4-zip php7.4-curl php7.4-mbstring php7.4-mysql  curl wget zip  tidy unzip composer php7.4-dev php7.4-redis  php-redis libmcrypt-dev php-pear nodejs npm redis redis-server

sudo npm install npm@latest -g
sudo pecl channel-update pecl.php.net

sudo pecl install mcrypt-1.0.1

Ini hanya digunakan jika menggunakan PHP 7.2 atau 7.3

sudo nano /etc/php/7.2/cli/php.ini
  extension=mcrypt.so

git clone .... 
composer install 

Pastikan, menggunakan node versi v12.4.0.

Ketika melakukan composer install, ada warning : 

Package flow/jsonpath is abandoned, you should avoid using it. Use softcreatr/jsonpath instead.
Package imsglobal/lti is abandoned, you should avoid using it. No replacement was suggested.
Package phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested.
Package zendframework/zend-code is abandoned, you should avoid using it. Use laminas/laminas-code instead.
Package zendframework/zend-eventmanager is abandoned, you should avoid using it. Use laminas/laminas-eventmanager instead.
Package zendframework/zend-servicemanager is abandoned, you should avoid using it. Use laminas/laminas-servicemanager instead.
Warning ini bisa diabaikan.

Di file konfigurasi config/generis.conf.php, dua nilai berikut tidak boleh Kita ubah : LOCAL_NAMESPACE dan GENERIS_INSTANCE_NAME


MySQL 


sudo su -
mysql
create database <database>;
create user '<user>'@'localhost';
set password for '<user>'@'localhost' = PASSWORD('<password>');
grant all privileges on <database>.* to '<user>@'localhost' identified by '<password>';
flush privileges;
quit
exit

Pastikan, semua tabel harus menggunakan engine InnoDB, lihat catatan dibawah terkait crashnya MySQL ketika menggunakan MyISAM.

ALTER TABLE  results_storage ENGINE=InnoDB;
ALTER TABLE  statements ENGINE=InnoDB;
ALTER TABLE  tq_task_log ENGINE=InnoDB;
ALTER TABLE  user_last_activity_log ENGINE=InnoDB;
ALTER TABLE  webhook_event_log ENGINE=InnoDB;
ALTER TABLE  variables_storage ENGINE=InnoDB;
ALTER TABLE  data_privileges ENGINE=InnoDB;
ALTER TABLE  delivery_executions ENGINE=InnoDB;
ALTER TABLE  delivery_log ENGINE=InnoDB;
ALTER TABLE  delivery_monitoring ENGINE=InnoDB;
ALTER TABLE  diagnostic_report ENGINE=InnoDB;
ALTER TABLE  doctrine_migration_versions ENGINE=InnoDB;
ALTER TABLE  event_log ENGINE=InnoDB;
ALTER TABLE  kv_delivery_monitoring ENGINE=InnoDB;
ALTER TABLE  kv_store ENGINE=InnoDB;
ALTER TABLE  list_items ENGINE=InnoDB;
ALTER TABLE  notifications  ENGINE=InnoDB;
ALTER TABLE  results_storage ENGINE=InnoDB;
ALTER TABLE  statements ENGINE=InnoDB;
ALTER TABLE  tq_task_log ENGINE=InnoDB;
ALTER TABLE  user_last_activity_log ENGINE=InnoDB;
ALTER TABLE  webhook_event_log ENGINE=InnoDB;
ALTER TABLE  lti_result_identifiers ENGINE=InnoDB;

PostgreSQL 


...

taoEdge

Ketika kita ingin menginstall versi terbaru tao dari github, setiap extension nya kita gunakan versi terbaru, jika kita mencoba menginstall nya dengan web installer, maka pada saat tulisan ini dibuat, masih terjadi error seperti saya laporkan di forum. Tapi, jika kita menggunakan command line installer, masalah ini tidak akan terjadi : 

#!/bin/bash

php tao/scripts/taoInstall.php --db_driver=pdo_pgsql --db_host=localhost --db_name=tao --db_pass=password --db_user=tao --file_path=/path/to/tao-data-dir --timezone="Asia/Jakarta" --url=http://tao.openthinklabs --user_login="username" --user_pass="password" --verbose --operated_by_name="OpenThink Labs" --operated_by_email="info@openthinklabs.com"

Enable MathJax

cd package-tao ; 
wget -c https://hub.taotesting.com/resources/taohub-articles/articles/third-party/MathJax_Install_TAO_3x.sh
chmod +x MathJax_Install_TAO_3x.sh
./MathJax_Install_TAO_3x.sh

Konfigurasi MathJax nya dapat dilakukan di : tao/views/templates/client_config.tpl

Guest Access


Activate Guest Access

sudo -u www-data php index.php 'oat\taoDeliveryRdf\scripts\ToggleGuestAccess' on

Deactivate Guest Access
sudo -u www-data php index.php 'oat\taoDeliveryRdf\scripts\ToggleGuestAccess' off

Menghapus semua Konten di TAO

[2] Menjelaskan dengan cukup detail : 

1. Hapus semua taoItems 

sudo -u www-data php index.php 'oat\tao\scripts\tools\CleanClass' taoItems_models_classes_ItemsService taoItems

2. Hapus semua konten dari : 

/data/generis/cache
/data/generis/serviceState
/data/tao/private
/data/tao/public
/data/taoItems/itemData
/data/taoQtiItem
/data/taoQtiTest
/data/tmp
3. Hapus/truncate semua data di tabel variables_storage, results_storage

TAO Config


Javascript Operation Timeout

Kita harus menaikkan nilai timeout javascript di

config/tao/js.conf.php 
, menjadi nilai yang lebih tinggi, dapat disamakan dengan timeout global yg kita definisikan di php-fpm ataupun nginx, disini saya definisikan timeout nya 300 deik. 

Extensions

Extensions manager

Extension dapat diinstall via web atau via CLI.  Agar dapat menginstall extension via web, pastikan menset nilai DEBUG_MODA = true di config/generis.conf.php. 

Jika via CLI, dapat menggunakan perintah : php tao/scripts/installExtension.php, informasi selengkapnya baca dokumentasi https://hub.taotesting.com/articles/how-to-make-a-new-extension-3-0-v2/how-to-install-an-extension

1. oat-sa/generis 


Feature/fluentd handler configure with fqcn, https://github.com/oat-sa/generis/pull/880
Feature/enhance cloud watch logs json formatter, https://github.com/oat-sa/generis/pull/879

2. oat-sa/tao-core

Jika DEBUG_MODE di config/generis.conf.php diset false, maka pada halaman extension manager, bagian Available Extensions tidak akan muncul.

3.  oat-sa/extension-tao-community

....

4. oat-sa/extension-tao-funcacl

....

5. oat-sa/extension-tao-dac-simple

....

6. oat-sa/extension-tao-testtaker

Untuk mengatur password constraing, dapat dilakukan di :

config/tao/passwordConstraints.conf.php

Defaultnya adalah :

return new \oat\tao\model\password\PasswordConstraintsService([
    'constraints' =>
        [
            'length' => 4,
            'upper'  => false,
            'lower'  => true,
            'number' => false,
            'spec'   => false
        ]
]);

Jika ingin bisa angka saja, bisa diubah menjadi : 
return new oat\tao\model\password\PasswordConstraintsService(array(
    'constraints' => array(
        'length' => 4,
        'upper' => false,
        'lower' => false,
        'number' => false,
        'spec' => false
    )
));


7. oat-sa/extension-tao-group

....

8. oat-sa/extension-tao-item

....

9. oat-sa/extension-tao-itemqti 

....

10. oat-sa/extension-tao-itemqti-pci

.....

12.  oat-sa/extension-tao-itemqti-pic

....

13. oat-sa/extension-tao-test

....

14. oat-sa/extension-tao-testqti

Bagaimana cara agar timer ujian berhenti ketika misalnya koneksi internet putus ? 

 'timer' => array(
            'target' => 'client'
        ),
.....
        'bootstrap' => array(
            'serviceExtension' => 'taoQtiTest',
            'serviceController' => 'Runner',
            'timeout' => 5,
            'communication' => array(
                'enabled' => true,
                'type' => 'poll',
                'extension' => null,
                'controller' => null,
                'action' => 'messages',
                'syncActions' => array(
                    'move',
                    'skip',
                    'storeTraceData',
                    'timeout',
                    'exitTest'
                ),
                'service' => null,
                'params' => array(
                )
            )
        ),
.....

Untuk informasi lebih detail tentang extention ini dapat membaca : 

Enhance the user experience with Test Plugins, https://github.com/oat-sa/taohub-articles/blob/master/articles/Test%20Runner%20Plugins/test-runner-plugins.md

15. oat-sa/extension-tao-outcome

....

16. oat-sa/extension-tao-outcomeui

RE-228: fix: show trace variables of answer on result page, https://github.com/oat-sa/extension-tao-outcomeui/pull/370

17. oat-sa/extension-tao-outcomerds

...

18. oat-sa/extension-tao-outcomekeyvalue

....

19. oat-sa/extension-tao-outcomelti

....

20. oat-sa/extension-tao-delivery

....

21. oat-sa/extension-tao-lti

.....

22. oat-sa/extension-tao-ltideliveryprovider

....

23. oat-sa/extension-tao-revision

....

24.  oat-sa/extension-tao-mediamanager"

Feature/AUT-17/Support multiple column layout in passage,  https://github.com/oat-sa/extension-tao-mediamanager/pull/250
Feature/con 271/store css within passages, https://github.com/oat-sa/extension-tao-mediamanager/pull/250

25. oat-sa/extension-tao-lti

....

26. oat-sa/extension-pcisample

Feature/tr 552 make text reader pci to ims compliant, https://github.com/oat-sa/extension-pcisample/pull/87

27. oat-sa/extension-tao-backoffice

....

28. oat-sa/extension-tao-proctoring

Delivery dapat dihentikan secara otomatis ketika waktu mengerjakan telah mencapai batas akhir yg ditentukan. 

Tuning Proctoring 
Untuk tuning dapat memperhatikan konfigurasi berikut : 
config/taoProctoring/DeliveryMonitoring.conf.php
config/taoProctoring/DeliveryLog.conf.php

Menambah Waktu Ujian Peserta
Dalam dokumentasi, dijelaskan jika proctor dapat menambah waktu ujian peserta, dikode jelas fungsionalitas ini ada, tapi ketika di antarmukanya, belum ditemukan bagaimana cara menambah waktu ujian seorang peserta ujian.

29. oat-sa/extension-tao-clientdiag

feat: update os/browser compatibility list, https://github.com/oat-sa/extension-tao-clientdiag/pull/290

30. oat-sa/extension-tao-eventlog

....

31. oat-sa/extension-tao-task-queue 

...

32. oat-sa/extension-tao-testqti-previewer

....

33. oat-sa/extension-tao-oauth

Membuat client key & secret :

php index.php '\oat\taoOauth\scripts\tools\GenerateCredentials' -r http://www.tao.lu/Ontologies/TAO.rdf#GlobalManagerRole

php index.php '\oat\taoOauth\scripts\tools\GenerateCredentials' -r 'http://tao.local/mytao.rdf#i62b1b1956be4c45877565bd13fc04cecc7'

http://tao.local/mytao.rdf#i62b1b1956be4c45877565bd13fc04cecc7 merupakan custom role yang dibuat dengan akses yg kita tentukan.

Untuk Role, gunakan Resouce Identifiernya, bukan namanya.

34. oat-sa/extension-tao-theming-platform

Ketika proses instalasi error, hapus ekstensi ini dari daftar di config/generis/installation.conf.php kemudian edit file config/generis/filesystem.conf.php dan tambahkan : 

'themingAssetsStorage' => 'default'

Jika sudah, klik install. Tampilannya akan seperi ini : 


Hanya saja, ketika mencoba upload file css, masih error, dengan pesan berikut : 
{
    "success": false,
    "type": "Exception",
    "message": "No datasource defined for taoThemingPlatform data storage.",
    "data": {
        "ExceptionType": "common_Exception"
    }
}

Versi ekstension yang digunakan v5.1.0

Jika ingin mengubah themes secara hardcode dapat dilakukan dengan cara berikut : 

1. Buat class theme di : tao/models/classes/theme/OpenThinkLabsTheme.php

2. Edit class theme default yang digunakan menjadi class theme yg sudah kita buat diatas. config/tao/theming.conf.php

3. Edit file tao/views/build/grunt/sass.js, lalu tambahkan scss untuk theme kita : 

tao: {
  files : {
    '../css/tao-main-style.css' : '../scss/tao-main-style.scss',
    '../css/tao-3.css' : '../scss/tao-3.scss',
    '../css/openthinklabs-theme/openthinklabs-3.css' : '../scss/openthinklabs-theme/openthinklabs-3.scss',
    '../css/layout.css' : '../scss/layout.scss',
    '../css/error-page.css': '../scss/error-page.scss',
    '../js/lib/jsTree/themes/css/style.css' : '../js/lib/jsTree/themes/scss/style.scss'
  }
},

Jika file scss nya dibuat, tinggal build dengan perintah : 

grunt taosass

35. oat-sa/generis-auth-keyvalue

....

36. oat-sa/extension-tao-testcenter

....

37. oat-sa/extension-tao-test-runner-plugins

....



3. extension-tao-clientdiag


taoClientDiagnostic, Browser and OS diagnostic tool


Ektension ini digunakan untuk memeriksa OS dan browser dari client. Untuk demo dapat melihat di : https://florida-auth.taocloud.org///index . 

Menu ke extension ini seharusnya dapat otomatis dibuat muncul di halaman login, melalui entrypoint (config/tao/entrypoint.conf.php) tapi dokumentasinya masih minim, jadi sementara, kita kustom (branch extension-tao-clientdiag-custom) dulu dengan mencontoh guestaccess entrypoint. 

Hasil diagnostiknya disimpan pada tabel diagnostic_report, untuk informasi detail dapat membaca https://github.com/oat-sa/taohub-articles/blob/master/technical-documentation/tao-clientdiag/results-description.md

5. PCI/PIC (Portable Custom Interactions) development

Untuk pengembangan custom interaction, dapat membaca panduan ini sebagai awalan. Salah satu contoh yg diberikan adalah TextReaderInteraction

TextReaderInteraction

Instalasi pciSamples dapat juga dilakukan dengan command line : 

php tao/scripts/installExtension.php pciSamples
Text reader digunakan untuk menampilkan soal berbentuk paragraf. Jika ingin paragraf berdampingan dengan soal-soalnya [4], kita bisa mengaktifkan opsi multi-column, maka kita perlu meng-aktifkan opsi 'multi-column' pada konfigurasi : 
config/taoQtiItem/qtiCreator.conf.php

6.  extension-tao-task-queue ( taoTaskQueue )

Untuk informasi lebih lanjut terkait extension ini, silahkan baca dokumentasinya https://hub.taotesting.com/techdocs/tao-task-queue/readme-distributed-task-queue atau git reponya https://github.com/oat-sa/extension-tao-task-queue


Server 

Apache


Untuk menghindari error yg dijelaskan disini, ubah : 

/etc/httpd/conf/modesecurity/modsecurity.conf

and increase this value from 1310720(128K) to higher:
SecRequestBodyLimit 1310720

Nginx 


Meskipun Nginx tidak secara resmi didukung, tetapi selama menggunakan Tao dengan nginx, tidak ditemukan kendalam berarti.

Contoh konfigurasi untuk Nginx dapat dilihat di : https://gist.github.com/wildanm/f7446ace51131512acc11a5b1d2d8d35

Untuk menghindari Error: 0 : timeout dari TAO, 
Disini dibuat agak besar, karena untuk Dashboard yg menyebar qti packages ke beberapa server, harus dicari solus yg lebih baik dari ini.

Nginx 504 Gateway Timeout / Nginx 502 Bad Gateway


nginx.conf 
fastcgi_read_timeout 60000s;
keepalive_timeout 60000;

php.ini

max_execution_time = 60000
default_socket_timeout = 60000

php-fpm.d/www.conf

request_terminate_timeout = 60000

Membuat item test secara programatik 



Roles


Di TAO ada beberapa roles : Global Manager,  Item Author, Lock Manager, Operational Administrator, REST Publisher, Readiness checker, Reviewer Role, System Administrator, Task Queue Manager, Test Author, Test Taker, Test XML Editor

1. Global Manager
..

2. Item Author
...

3. Lock Manager
...

4. Operational Administrator
...

5. REST Publisher
...

6. Readiness checker
...

7. Reviewer Role
...

8. System Administrator
...

9.Task Queue Manager
...

10. Test Author
...

11. Test Taker
...

12. Test XML Editor
....

Rest API



Redis 

Untuk skalabilitas TAO, sebaiknya Kita menggunakan Redis, karena jika tidak, ketika test taker, peserta ujian > 200 orang, maka TAO akan kewalahan melayani, jika menggunakan MySQL jika konfigurasinya tidak optimal, CPU usage nya akan sangat tinggi, jika konfigurasi php-fpm, tidak optimal, diawal ujian, ketika peserta > 200 orang, terkang tiba-tiba php-fpm hang. Dengan menggunakan redis, diharapkan, kendala seperti diatas, tidak terjadi lagi. 

Konfigurasi yang harus diubah : 

config/taoDelivery/execution_service.conf.php
config/generis/uriProvider.conf.php
config/tao/stateStorage.conf.php
config/tao/session.conf.php
config/generis/auth.conf.php
config/generis/persistences.conf.php


config/taoDelivery/execution_service.conf.php

return new oat\taoDelivery\model\execution\implementation\KeyValueService(array(
'persistence' => 'deliveryExecution'
));

config/generis/uriProvider.conf.php

return new core_kernel_uri_AdvKeyValueUriProvider(
array(
'persistence' => 'uriProvider',
'namespace' => LOCAL_NAMESPACE.'#'
)
);

config/tao/stateStorage.conf.php

return new tao_models_classes_service_StateStorage(array(
'persistence' => 'serviceState'
));

config/tao/session.conf.php

return new common_session_php_KeyValueSessionHandler(array(
common_session_php_KeyValueSessionHandler::OPTION_PERSISTENCE => 'session'
));

config/generis/auth.conf.php

return new oat\oatbox\config\ConfigurationService(array(
'config' => array(
array(
'driver' => 'oat\\authKeyValue\\AuthKeyValueAdapter'
),
array(
'driver' => 'oat\\generis\\model\\user\\AuthAdapter',
'user_factory' => 'generis/userFactory'
)
)
));

config/generis/persistences.conf.php 

return new oat\generis\persistence\PersistenceManager(array(
'persistences' => array(
'default' => array(
'driver' => 'dbal',
'connection' => array(
'driver' => 'pdo_pgsql',
'driverClass' => null,
'instance' => null,
'host' => 'localhost',
'dbname' => 'dbname',
'user' => 'username',
'password' => 'password',
'driverOptions' => array()
)
),

'serviceState' => array(
'driver' => 'phpredis',
'host' => '127.0.0.1',
'port' => 6379
//'driver' => 'phpfile'
),
'cache' => array(
'driver' => 'phpfile'
),
'session' => array(
'driver' => 'phpredis',
'host' => '127.0.0.1',
'port' => 6379
//'driver' => 'phpfile'
),
'deliveryExecution' => array(
'driver' => 'phpredis',
'host' => '127.0.0.1',
'port' => 6379
),
'uriProvider' => array(
'driver' => 'phpredis',
'host' => '127.0.0.1',
'port' => 6379
),
'authKeyValue' => array(
'driver' => 'phpredis',
'host' => '127.0.0.1',
'port' => 6379
),
'default_kv' => array(
'driver' => 'phpredis',
'host' => '127.0.0.1',
'port' => 6379
//'driver' => 'phpfile'
),
'maintenance' => array(
'driver' => 'phpfile'
)
)
));


php index.php 'oat\authKeyValue\action\ActivateKeyValueAuthentication' --persistence authKeyValue


Installl Redis di Mac : 

/usr/local/opt/php\@7.3/bin/pecl install redis

Jika mengalami masalah dengan Tao DeliveryExecution tracking service dengan redis, cara hack sementaranya. dapat dibaca di diskusi ini

Untuk selengkapnya baca [5]

Bahasa 

Untuk mengupdate bahasa, menambah bahasa, seperti bahasa Indonesia di TAO dapat menjalankan perintah : 

php tao/scripts/taoTranslate.php -force -v -a create -l id-ID -ll 'Indonesia' -u=username -p=password -e tao,ltiDeliveryProvider,taoGroups,taoMediaManager,taoTests,taoCe,taoItems,taoOutcomeUi,taoTestTaker,taoDelivery,taoQtiItem,taoDeliveryRdf,taoLti,taoQtiTest,taoClientDiagnostic,funcAcl,pciSamples,qtiItemPci,qtiItemPic,taoBackOffice,taoEventLog,taoProctoring,taoResultServer,taoRevision,taoDacSimple

download paket terjemahan untuk versi tao Anda, lalu jalankan :

./pootle_export_to_tao.sh  tao34 id-ID .

Lalu agar muncul pada pilihan bahasa, jalankan (cukup dijalankan sekali saja, kalau lebih dari sekali, sistem akan error) : 

php tao/scripts/taoRDFImport.php -v -n -u=username -p=password http://www.tao.lu/Ontologies/TAO.rdf# -i tao/locales/id-ID/lang.rdf 

Lakukan merge terjemahan :

./merge_all_translations.sh id-ID

Jika ingin membantu penerjamahan TAO kedalam bahasa Indonesia, dapat melalui https://translate.taotesting.com/user/system/

MariaDB Crash 

Ketika proctoring diaktifkan dengan 151 peserta, database tiba-tiba crash, error lengkapnya dapat dilihat di : https://gist.github.com/wildanm/57c79999894eb1f824793f974c9feda8 . dari lognya, kemungkinan besar, error terjadi karena ada tabel tabel yg masih menggunakan engine MyISAM yg crash, berikut daftar table beserta engine yang digunakan https://gist.github.com/wildanm/7330631eb7d2b835329c71301b812486

Solusi yang bisa dicoba adalah, mengubah seluruh tabel yang masih menggunakan MyISAM, menjadi InnoDB.

Google Cloud 


Agar ketika VM direstart, cloud sql proxy tetap berjalan, Kita dapat mengikuti langkah-langkah yang dijelaskan disini : https://gist.github.com/goodwill/a981c2912ae6a83761a624f657f34d9f

JMeter 


Stress Test TAO dengan JMeter.


Migrasi Server / Backup & Resptore

 
 define('ROOT_URL','http://cbt.openthinklabs/'); #pastikan akhirannya menggunakan forward slash (/)

Backup database yang digunakan : mysql/postgresql jika menggunakan redis, redis dibackup juga. Selain itu, backup juga folder-folder berikut pada directory data TAO Anda ; private/ , itemDirectory/ dan taoQtiTest.

Troubleshooting

Debugging 

config/generis/log.conf.php

return new oat\oatbox\log\LoggerService(array(
    'logger' => array(
        'class' => \oat\oatbox\log\logger\TaoMonolog::class,
        'options' => array(
            'name' => 'tao',
            'handlers' => array(
                array(
                    'class' => \Monolog\Handler\StreamHandler::class,
                    'options' => array(
                        '/opt/webapps/tao/logs/tao.log',
                        \Monolog\Logger::DEBUG
                    )
                )
            )
        )
)));

Selengkapnya. TAO System Debug 

Referensi

  1. TAO Hub, https://hub.taotesting.com/
  2. How to remove all content, almost like a fresh installation?, https://forum.taotesting.com/discussion/407/how-to-remove-all-content-almost-like-a-fresh-installation
  3. ACT Invests in Open Assessment Technologies (OAT), the Global Leader for Open Source Assessment Solutions, https://leadershipblog.act.org/2018/09/act-invests-in-open-assessment.html
  4. TAO 3.3.0-sprint71, https://www.loom.com/share/88d46873eacc4a49bfdbad8adc4ea7f9
  5. Data abstractions, https://hub.taotesting.com/articles/administrator-guide/data-abstractions
  6. TAO User Guide, https://www.taotesting.com/user-guide/users/introduction/about-the-guide/
  7. tao-docker, https://gitlab.telecomnancy.univ-lorraine.fr/telecomnancy/tao-docker