Initial snapshot

This commit is contained in:
Mercier Pierre-Olivier 2013-02-11 22:04:30 +01:00
commit fee4dd4e6d
373 changed files with 62144 additions and 0 deletions

60
test/Makefile Normal file
View file

@ -0,0 +1,60 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/kaneton/export/output/kaneton/test/Makefile
#
# created julien quintard [fri jun 29 11:19:40 2007]
# updated julien quintard [sat feb 5 12:10:10 2011]
#
#
# ---------- component --------------------------------------------------------
#
component := test
#
# ---------- dependencies -----------------------------------------------------
#
include ../environment/env.mk
#
# ---------- directives -------------------------------------------------------
#
.PHONY: main clear prototypes headers
#
# ---------- variables --------------------------------------------------------
#
SUBDIRS := client \
packages
#
# ---------- rules ------------------------------------------------------------
#
main:
clear:
for d in $(SUBDIRS) ; do \
$(call env_launch,$${d}/Makefile,clear,) ; \
done
$(call env_purge,)
prototypes:
for d in $(SUBDIRS) ; do \
$(call env_launch,$${d}/Makefile,clear,) ; \
done
headers:
for d in $(SUBDIRS) ; do \
$(call env_launch,$${d}/Makefile,clear,) ; \
done

15
test/README Normal file
View file

@ -0,0 +1,15 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/kaneton.STABLE/test/README
#
# created julien quintard [tue nov 2 07:38:27 2010]
# updated julien quintard [tue nov 2 07:39:23 2010]
#
This directory contains the whole test system which is composed of a server,
a client, some scripts as well as test suites composed of several tests.

61
test/client/Makefile Normal file
View file

@ -0,0 +1,61 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/kaneton/test/client/Makefile
#
# created julien quintard [fri jun 29 11:19:40 2007]
# updated julien quintard [thu feb 10 10:35:45 2011]
#
#
# ---------- dependencies -----------------------------------------------------
#
include ../../environment/env.mk
#
# ---------- directives -------------------------------------------------------
#
.PHONY: main build run clear prototypes headers information- \
information test- test list- list display- display \
submit submit-
#
# ---------- rules ------------------------------------------------------------
#
main:
$(call env_launch,$(_TEST_CLIENT_SCRIPT_),,)
information- information:
$(call env_launch,$(_TEST_CLIENT_SCRIPT_),$@,)
test- test:
$(call env_launch,$(_TEST_CLIENT_SCRIPT_),$@,)
test-%:
$(call env_launch,$(_TEST_CLIENT_SCRIPT_),$@,)
retest- retest:
$(call env_launch,$(_TEST_CLIENT_SCRIPT_),$@,)
retest-%:
$(call env_launch,$(_TEST_CLIENT_SCRIPT_),$@,)
submit- submit:
$(call env_launch,$(_TEST_CLIENT_SCRIPT_),$@,)
submit-%:
$(call env_launch,$(_TEST_CLIENT_SCRIPT_),$@,)
clear:
$(call purge,)
prototypes:
headers:

165
test/client/README Normal file
View file

@ -0,0 +1,165 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/kaneton/test/client/README
#
# created julien quintard [tue nov 2 05:48:57 2010]
# updated julien quintard [thu feb 10 11:17:07 2011]
#
The client script provides the user the possibility to request actions
from the test server.
$> cd ~/kaneton/test/client/
$~/kaneton/test/client> make
[!] usage: client.py [command]
[!] commands:
[!] retest-[identifier]
[!] information
[!] test-[environment]::[suite]
[!] submit-[stage]
$~/kaneton/test/client>
#
# ---------- information ------------------------------------------------------
#
The 'information' command returns information on the user account including
the number of tests consumed, the number of tests left etc.
The example below illustrates this command.
$~/kaneton/test/client> make information
[+] configuration:
[+] server: https://test.opaak.org:8421
[+] capability: /data/mycure/repositories/kaneton/environment/profile/user/julien.quintard/julien.quintard.cap
[+] platform: ibm-pc
[+] architecture: ia32/educational
[+] information:
[+] profile:
[+] attributes:
[+] identifier: julien.quintard
[+] type: contributor
[+] members:
[+] name: Julien Quintard
[+] email: julien.quintard@gmail.com
[+] suites:
[+] k3: This test suite contains tests related to the execution.
[+] k2: This test suite focuses on the memory management.
[+] k1: This test suite focuses on the event processing.
[+] bugs: This suite contains the tests which fail on the official kaneton implementation.
[+] kaneton: This test suite triggers all the tests.
[+] stages:
[+] k3: This stage evaluates the kaneton's execution functionalities.
[+] k2: This stage evaluates the kaneton's memory management.
[+] k1: This stage evaluates the kaneton's event procesing capabilities.
[+] k0: This stage focuses on the assembly language and the boot process through BIOS services.
[+] environments:
[+] xen: The 'xen' environment is used to thoroughly test a kaneton implementation in a Xen hardware-assisted virtual machine.
[+] qemu: The 'qemu' environment is used to test a kaneton implementation through the QEMU processor emulator.
[+] database:
[+] quotas:
[+] xen:
[+] k3: -1
[+] k2: -1
[+] k1: -1
[+] bugs: -1
[+] kaneton: -1
[+] qemu:
[+] ibm-pc.ia32/educational:
[+] k3: -1
[+] k2: -1
[+] k1: -1
[+] bugs: -1
[+] kaneton: -1
[+] reports:
[+] xen:
[+] ibm-pc.ia32/educational:
[+] k3:
[+] k2:
[+] k1:
[+] bugs:
[+] kaneton:
[+] qemu:
[+] ibm-pc.ia32/educational:
[+] k3:
[+] k2:
[+] k1:
[+] bugs:
[+] kaneton:
$~/kaneton/test/client>
#
# ---------- test -------------------------------------------------------------
#
The 'test' command issues a request for a test suite to be run in the given
environment so that to stress the current kaneton implementation.
The syntax for this command is test-[environment]::[suite] where [suite]
can be any of the 'k1', 'k2', 'k3' etc. stages while [environment] can
be 'xen' or 'qemu'. For more information regarding the available suites,
stages, environments etc., please refer to the 'information' command.
$~/kaneton/test/client> make test-xen::k1
[+] configuration:
[+] server: https://test.opaak.org:8421
[+] capability: /data/mycure/repositories/kaneton/environment/profile/user/julien.quintard/julien.quintard.cap
[+] platform: ibm-pc
[+] architecture: ia32/educational
[+] generating the kaneton snapshot
[+] loading the kaneton snapshot
[+] requesting the server
[+] the snapshot has been scheduled for testing under the identifier: 20110210:105955
$~/kaneton/test/client>
#
# ---------- submit -----------------------------------------------------------
#
Finally, the 'submit' command enables students to definitely submit a
kaneton implementation so that their work gets evaluated afterwards according
to a specific stage.
The syntax for this command is submit-[stage].
$~/kaneton/test/client> make submit-k3
[+] configuration:
[+] server: https://test.opaak.org:8421
[+] capability: /data/mycure/repositories/kaneton/environment/profile/user/julien.quintard/julien.quintard.cap
[+] platform: ibm-pc
[+] architecture: ia32/educational
[+] generating the kaneton snapshot
[+] loading the kaneton snapshot
[+] requesting the server
[+] the snapshot has been submitted successfully
$~/kaneton/test/client>
#
# ---------- retest -----------------------------------------------------------
#
The 'retest' command provides the administrator the possibility to re-launch
the test suite according to the given identifier. This command is useful should
an unexpected error occur.
The syntax for this command is retest-[identifier].
$~/kaneton/test/client> make retest-20110210:105955
[+] configuration:
[+] server: https://test.opaak.org:8421
[+] capability: /data/mycure/repositories/kaneton/environment/profile/user/julien.quintard/julien.quintard.cap
[+] platform: ibm-pc
[+] architecture: ia32/educational
[+] requesting the server
[+] the snapshot has been re-tested successfully
$~/kaneton/test/client>

371
test/client/client.py Normal file
View file

@ -0,0 +1,371 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/kaneton/test/client/client.py
#
# created julien quintard [mon mar 23 00:09:51 2009]
# updated julien quintard [mon jun 13 23:39:28 2011]
#
#
# ---------- information ------------------------------------------------------
#
# this script connects to the test server and triggers operations.
#
# note that this script depends on the ktp package which relies on
# the pyopenssl, yaml and other packages.
#
#
# ---------- packages ---------------------------------------------------------
#
import sys
import env
import ktp
#
# ---------- globals ----------------------------------------------------------
#
g_server = None
g_capability = None
g_platform = None
g_architecture = None
#
# ---------- functions --------------------------------------------------------
#
#
# this function prints the usage.
#
def Usage():
command = None
env.display(env.HEADER_ERROR, "usage: client.py [command]",
env.OPTION_NONE)
env.display(env.HEADER_NONE, "", env.OPTION_NONE)
env.display(env.HEADER_ERROR, "commands:", env.OPTION_NONE)
for command in c_commands:
env.display(env.HEADER_ERROR, " " + command, env.OPTION_NONE)
#
# this function simply displays the current configuration.
#
def Warning():
env.display(env.HEADER_NONE, "", env.OPTION_NONE)
env.display(env.HEADER_OK, "configuration:", env.OPTION_NONE)
env.display(env.HEADER_OK,
" server: " + g_server,
env.OPTION_NONE)
env.display(env.HEADER_OK,
" capability: " + g_capability,
env.OPTION_NONE)
env.display(env.HEADER_OK,
" platform: " + str(g_platform),
env.OPTION_NONE)
env.display(env.HEADER_OK,
" architecture: " + str(g_architecture),
env.OPTION_NONE)
env.display(env.HEADER_NONE, "", env.OPTION_NONE)
#
# this function dumps any Python data structure in a hierarchical way.
#
def Dump(data, margin = "", alignment = 26):
key = None
length = None
if isinstance(data, dict):
for key in data:
if not isinstance(data[key], dict) and not isinstance(data[key], list):
length = len(margin) + len(str(key)) + 1
env.display(env.HEADER_OK,
margin + str(key) + ":" +
(alignment - length) * " " +
str(data[key]),
env.OPTION_NONE)
else:
env.display(env.HEADER_OK,
margin + str(key) + ":",
env.OPTION_NONE)
Dump(data[key], margin + " ", alignment)
elif isinstance(data, list):
for element in data:
Dump(element, margin, alignment)
else:
env.display(env.HEADER_OK,
alignment * " " +
str(data),
env.OPTION_NONE)
#
# this function asks the server for information related to
# the given capability hence user.
#
# these information are then displayed.
#
def Information(server, capability, arguments):
information = None
item = None
# check the arguments
if len(arguments) != 0:
Usage()
sys.exit(42)
# warning
Warning()
# retrieve the information.
information = ktp.xmlrpc.Call(server.Information(capability))
# display a message.
env.display(env.HEADER_OK,
"information:",
env.OPTION_NONE)
# dump the information dictionary.
Dump(information, " ")
#
# this function triggers a test.
#
def Test(server, capability, arguments):
snapshot = None
suite = None
environment = None
identifier = None
# warning
Warning()
# check the arguments
if len(arguments) != 2:
Usage()
sys.exit(42)
# retrieve the arguments.
environment = arguments[0]
suite = arguments[1]
# display a message.
env.display(env.HEADER_OK,
"generating the kaneton snapshot",
env.OPTION_NONE)
# export the current kaneton implementation.
env.launch(env._EXPORT_SCRIPT_,
"test:" + capability["type"],
env.OPTION_QUIET)
# display a message.
env.display(env.HEADER_OK,
"loading the kaneton snapshot",
env.OPTION_NONE)
# read the snapshot.
snapshot = env.pull(env._EXPORT_DIR_ + "/output/" + \
"test:" + capability["type"] + ".tar.bz2",
env.OPTION_NONE)
# display a message.
env.display(env.HEADER_OK,
"requesting the server",
env.OPTION_NONE)
# trigger a test.
identifier = ktp.xmlrpc.Call(server.Test(capability,
ktp.miscellaneous.Binary(snapshot),
g_platform,
g_architecture,
environment,
suite))
# display the received report.
env.display(env.HEADER_OK,
"the snapshot has been scheduled for testing under the " \
"identifier: " + identifier,
env.OPTION_NONE)
#
# this function requests the server for re-testing a snapshot.
#
def Retest(server, capability, arguments):
snapshot = None
identifier = None
# warning
Warning()
# check the arguments
if len(arguments) != 1:
Usage()
sys.exit(42)
# retrieve the arguments.
identifier = arguments[0]
# display a message.
env.display(env.HEADER_OK,
"requesting the server",
env.OPTION_NONE)
# trigger a test.
ktp.xmlrpc.Call(server.Retest(capability,
identifier))
# display a message.
env.display(env.HEADER_OK,
"the snapshot has been re-tested successfully",
env.OPTION_NONE)
#
# this function submits a snapshot.
#
def Submit(server, capability, arguments):
snapshot = None
stage = None
# warning
Warning()
# check the arguments
if len(arguments) != 1:
Usage()
sys.exit(42)
# retrieve the arguments.
stage = arguments[0]
# check if there is a 'snapshot.tar.bz2' in the client/ directory.
if env.path(env._TEST_CLIENT_DIR_ + "/snapshot.tar.bz2",
env.OPTION_EXIST):
# display a message.
env.display(env.HEADER_OK,
"loading the snapshot '" + \
env._TEST_CLIENT_DIR_ + "/snapshot.tar.bz2'",
env.OPTION_NONE)
# read the snapshot.
snapshot = env.pull(env._TEST_CLIENT_DIR_ + "/snapshot.tar.bz2",
env.OPTION_NONE)
else:
# display a message.
env.display(env.HEADER_OK,
"generating the kaneton snapshot",
env.OPTION_NONE)
# export the current kaneton implementation.
env.launch(env._EXPORT_SCRIPT_,
"test:" + capability["type"],
env.OPTION_QUIET)
# display a message.
env.display(env.HEADER_OK,
"loading the kaneton snapshot",
env.OPTION_NONE)
# read the snapshot.
snapshot = env.pull(env._EXPORT_DIR_ + "/output/" + \
"test:" + capability["type"] + ".tar.bz2",
env.OPTION_NONE)
# display a message.
env.display(env.HEADER_OK,
"requesting the server",
env.OPTION_NONE)
# submit the snapshot.
ktp.xmlrpc.Call(server.Submit(capability,
ktp.miscellaneous.Binary(snapshot),
stage))
# display a message.
env.display(env.HEADER_OK,
"the snapshot has been submitted successfully",
env.OPTION_NONE)
#
# this is the main function.
#
def Main():
global g_server
global g_capability
global g_platform
global g_architecture
server = None
capability = None
command = None
arguments = None
# retrieve the command.
if len(sys.argv) != 2:
Usage()
sys.exit(42)
# set the command.
command = sys.argv[1].split("-")[0]
# set the variables.
g_server = env._TEST_SERVER_
g_capability = env._TEST_CAPABILITY_
g_platform = env._TEST_PLATFORM_
g_architecture = env._TEST_ARCHITECTURE_
# connect to the server.
server = ktp.xmlrpc.Connect(g_server)
# load the student capability.
capability = ktp.capability.Load(g_capability)
# trigger the appropriate command.
for name in c_commands:
if command == name.split("-")[0]:
# set the arguments.
if len(sys.argv[1].split("-")) > 1:
arguments = sys.argv[1].split("-")[1].split("::")
else:
arguments = []
c_commands[name](server, capability, arguments)
sys.exit(0)
# wrong command.
env.display(env.HEADER_ERROR,
"unknown command '" + arguments[0] + "'",
env.OPTION_NONE)
# display usage.
Usage()
#
# ---------- constants --------------------------------------------------------
#
c_commands = {
"information": Information,
"test-[environment]::[suite]": Test,
"retest-[identifier]": Retest,
"submit-[stage]": Submit
}
#
# ---------- entry point ------------------------------------------------------
#
if __name__ == '__main__':
Main()

43
test/packages/Makefile Normal file
View file

@ -0,0 +1,43 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/kaneton.STABLE/test/package/Makefile
#
# created julien quintard [wed may 16 18:08:19 2007]
# updated julien quintard [mon oct 25 20:53:32 2010]
#
#
# ---------- dependencies -----------------------------------------------------
#
include ../../environment/env.mk
#
# ---------- directives -------------------------------------------------------
#
.PHONY: main clear
#
# ---------- variables --------------------------------------------------------
#
SUBDIRS := ktp
#
# ---------- rules ------------------------------------------------------------
#
main:
clear:
for d in $(SUBDIRS) ; do \
$(call env_launch,$${d}/Makefile,clear,) ; \
done
$(call env_purge)

View file

@ -0,0 +1,33 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/kaneton.STABLE/test/package/ktp/Makefile
#
# created julien quintard [wed may 16 18:08:19 2007]
# updated julien quintard [mon oct 25 20:53:04 2010]
#
#
# ---------- dependencies -----------------------------------------------------
#
include ../../../environment/env.mk
#
# ---------- directives -------------------------------------------------------
#
.PHONY: main clear
#
# ---------- rules ------------------------------------------------------------
#
main:
clear:
$(call env_purge)

View file

@ -0,0 +1,58 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/__init__.py
#
# created julien quintard [mon oct 25 19:43:41 2010]
# updated julien quintard [wed feb 16 13:31:24 2011]
#
#
# ---------- information ------------------------------------------------------
#
# the kaneton test package contains everything necessary for the scripts
# to perform cryptographic tasks, issuing remote requests and so on.
#
# note that this package is even more important for the server script which
# evolves outside the kaneton environment, hence does not have access to
# the kaneton environment functionalities. this is why this package provides
# features for reading and writing files for instance.
#
#
# ---------- definitions ------------------------------------------------------
#
StatusOk = True
StatusError = False
StatusUnknown = -666
#
# ---------- modules ----------------------------------------------------------
#
import bulletin
import capability
import certificate
import code
import configuration
import database
import environment
import hook
import key
import log
import manifest
import miscellaneous
import process
import queue
import report
import snapshot
import stage
import statement
import suite
import trace
import xmlrpc

View file

@ -0,0 +1,41 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/bulletin.py
#
# created julien quintard [mon oct 25 20:23:05 2010]
# updated julien quintard [wed oct 27 13:08:57 2010]
#
#
# ---------- packages ---------------------------------------------------------
#
import yaml
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".blt"
#
# ---------- functions --------------------------------------------------------
#
#
# this function stores a bulletin.
#
def Store(bulletin, path):
yaml.dump(bulletin,
file(path, 'w'))
#
# this function loads a bulletin.
#
def Load(path):
return yaml.load(file(path, 'r'))

View file

@ -0,0 +1,111 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/kaneton/test/packages/ktp/capability.py
#
# created julien quintard [mon oct 25 19:58:10 2010]
# updated julien quintard [wed feb 9 06:42:08 2011]
#
#
# ---------- packages ---------------------------------------------------------
#
from OpenSSL import crypto
import os
import hmac
import pickle
import re
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".cap"
TypeContributor = "contributor"
TypeGroup = "group"
TypeStudent = "student"
#
# ---------- functions --------------------------------------------------------
#
#
# this function returns a list of capability identifiers.
#
def List(directory):
capabilities = []
entries = None
entry = None
path = None
entries = os.listdir(directory)
for entry in entries:
path = directory + "/" + entry
if os.path.isfile(path) and re.search("^.*" + Extension + "$", path):
capabilities += [ entry[:-len(Extension)] ]
return capabilities
#
# this function creates a capability.
#
def Create(code,
identifier,
type,
attributes,
members):
h = hmac.new(code, pickle.dumps( (identifier,
type,
str(attributes),
str(members)) ))
token = h.hexdigest()
capability = { "identifier": identifier,
"type": type,
"attributes": attributes,
"members": members,
"token": token }
return capability
#
# this function validates the capability according to the given
# key that has been used for issuing this capability.
#
def Validate(code,
capability):
h = hmac.new(code,
pickle.dumps( (capability["identifier"],
capability["type"],
str(capability["attributes"]),
str(capability["members"]) )))
token = h.hexdigest()
if token != capability["token"]:
return False
return True
#
# this function stores a capability on the file system.
#
def Store(path,
capability):
open(path, 'w').write(pickle.dumps(capability))
#
# this function loads a capability from the file system.
#
def Load(path):
capability = pickle.loads(open(path, 'r').read())
return capability

View file

@ -0,0 +1,84 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/certificate.py
#
# created julien quintard [mon oct 25 20:01:03 2010]
# updated julien quintard [wed oct 27 13:10:06 2010]
#
#
# ---------- packages ---------------------------------------------------------
#
from OpenSSL import crypto
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".crt"
#
# ---------- functions --------------------------------------------------------
#
#
# this function returns a certificate request.
#
def Request(key,
digest = "md5",
**attributes):
request = crypto.X509Req()
subject = request.get_subject()
for (k, v) in attributes.items():
setattr(subject, k, v)
request.set_pubkey(key)
request.sign(key, digest)
return request
#
# this function creates a certificate according to the given
# certificate request.
#
def Create(request,
issuer,
serial,
timestamp,
digest = "md5"):
issuer_certificate = None
issuer_key = None
timestamp_notbefore = None
timestamp_notafter = None
(issuer_certificate, issuer_key) = issuer
(timestamp_notbefore, timestamp_notafter) = timestamp
certificate = crypto.X509()
certificate.set_serial_number(serial)
certificate.gmtime_adj_notBefore(timestamp_notbefore)
certificate.gmtime_adj_notAfter(timestamp_notafter)
certificate.set_issuer(issuer_certificate.get_subject())
certificate.set_subject(request.get_subject())
certificate.set_pubkey(request.get_pubkey())
certificate.sign(issuer_key, digest)
return certificate
#
# this function stores the given certificate on the file system.
#
def Store(path,
certificate):
open(path,
'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, certificate))

55
test/packages/ktp/code.py Normal file
View file

@ -0,0 +1,55 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/kaneton.STABLE/test/packages/ktp/code.py
#
# created julien quintard [mon oct 25 20:03:52 2010]
# updated julien quintard [sat oct 30 11:17:56 2010]
#
#
# ---------- packages ---------------------------------------------------------
#
import random
import string
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".code"
#
# ---------- functions --------------------------------------------------------
#
#
# this function generates a random code.
#
def Generate():
random.seed()
code = "".join([ random.choice(string.ascii_letters + string.punctuation)
for x in range(128) ])
return code
#
# this function stores a code on the file system.
#
def Store(path,
code):
open(path, 'w').write(code)
#
# this function reads a code file from the file system
#
def Load(path):
code = open(path, 'r').read()
return code

View file

@ -0,0 +1,34 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANE...EST-SYSTEM/packages/ktp/configuration.py
#
# created julien quintard [mon oct 25 20:22:05 2010]
# updated julien quintard [wed oct 27 13:11:00 2010]
#
#
# ---------- packages ---------------------------------------------------------
#
import yaml
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".conf"
#
# ---------- functions --------------------------------------------------------
#
#
# this function loads a configuration.
#
def Load(path):
return yaml.load(file(path, 'r'))

View file

@ -0,0 +1,68 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/database.py
#
# created julien quintard [mon oct 25 20:23:05 2010]
# updated julien quintard [thu feb 3 23:58:14 2011]
#
#
# ---------- packages ---------------------------------------------------------
#
import yaml
import os
import re
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".db"
#
# ---------- functions --------------------------------------------------------
#
#
# this function returns a list of database identifiers.
#
def List(directory):
databases = []
entries = None
entry = None
path = None
entries = os.listdir(directory)
for entry in entries:
path = directory + "/" + entry
if os.path.isfile(path) and re.search("^.*" + Extension + "$", path):
databases += [ entry[:-len(Extension)] ]
return databases
#
# this function generates a database based on the given configuration.
#
def Generate(configuration):
return configuration
#
# this function stores a database.
#
def Store(database, path):
yaml.dump(database,
file(path, 'w'))
#
# this function loads a database.
#
def Load(path):
return yaml.load(file(path, 'r'))

View file

@ -0,0 +1,65 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/environment.py
#
# created julien quintard [mon oct 25 20:23:05 2010]
# updated julien quintard [wed feb 2 22:57:01 2011]
#
#
# ---------- packages ---------------------------------------------------------
#
import yaml
import os
import re
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".env"
QEMU = "qemu"
Xen = "xen"
#
# ---------- functions --------------------------------------------------------
#
#
# this function returns a list of environment identifiers.
#
def List(directory):
environments = []
entries = None
entry = None
path = None
entries = os.listdir(directory)
for entry in entries:
path = directory + "/" + entry
if os.path.isfile(path) and re.search("^.*" + Extension + "$", path):
environments += [ entry[:-len(Extension)] ]
return environments
#
# this function stores a environment.
#
def Store(environment, path):
yaml.dump(environment,
file(path, 'w'))
#
# this function loads a environment.
#
def Load(path):
return yaml.load(file(path, 'r'))

37
test/packages/ktp/hook.py Normal file
View file

@ -0,0 +1,37 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/hook.py
#
# created julien quintard [mon oct 25 19:58:10 2010]
# updated julien quintard [thu feb 3 23:56:36 2011]
#
#
# ---------- packages ---------------------------------------------------------
#
import os
import yaml
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".hk"
#
# ---------- functions --------------------------------------------------------
#
#
# this function loads the hooks dispatcher.
#
def Load(directory):
path = directory + "/hooks" + Extension
return yaml.load(file(path, 'r'))

47
test/packages/ktp/key.py Normal file
View file

@ -0,0 +1,47 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/key.py
#
# created julien quintard [mon oct 25 20:11:55 2010]
# updated julien quintard [wed oct 27 13:11:59 2010]
#
#
# ---------- packages ---------------------------------------------------------
#
from OpenSSL import crypto
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".key"
#
# ---------- functions --------------------------------------------------------
#
#
# this function generates a cryptographic key.
#
def Generate(type = crypto.TYPE_RSA,
length = 2048):
key = crypto.PKey()
key.generate_key(type, length)
return key
#
# this function stores a key.
#
def Store(path,
key):
open(path,
'w').write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key))

50
test/packages/ktp/log.py Normal file
View file

@ -0,0 +1,50 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/log.py
#
# created julien quintard [mon oct 25 19:58:10 2010]
# updated julien quintard [tue mar 8 11:49:26 2011]
#
#
# ---------- packages ---------------------------------------------------------
#
import os
import time
import fcntl
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".log"
#
# ---------- functions --------------------------------------------------------
#
#
# this function records the given message within the current log file.
#
def Record(directory, message):
handle = None
header = None
path = None
path = directory + "/" + time.strftime("%Y%m%d") + Extension
header = time.strftime("[%Y/%m/%d %H:%M:%S] ")
handle = open(path, "a")
fcntl.flock(handle.fileno(), fcntl.LOCK_EX)
handle.write(header + message + "\n")
handle.close()

View file

@ -0,0 +1,34 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/manifest.py
#
# created julien quintard [wed oct 27 10:53:58 2010]
# updated julien quintard [tue dec 7 13:41:02 2010]
#
#
# ---------- packages ---------------------------------------------------------
#
import yaml
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".mnf"
#
# ---------- functions --------------------------------------------------------
#
#
# this function loads a manifest.
#
def Load(path):
return yaml.load(file(path, 'r'))

View file

@ -0,0 +1,282 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANE...EST-SYSTEM/packages/ktp/miscellaneous.py
#
# created julien quintard [mon oct 25 19:51:49 2010]
# updated julien quintard [sun feb 20 01:00:57 2011]
#
#
# ---------- packages ---------------------------------------------------------
#
import xmlrpclib
import tempfile
import os
import shutil
import re
import ktp
#
# ---------- definitions ------------------------------------------------------
#
OptionNone = 0
OptionFile = 1
OptionDirectory = 2
OptionRecursive = 3
#
# ---------- functions --------------------------------------------------------
#
#
# this function converts some data into its binary form.
#
def Binary(data):
return xmlrpclib.Binary(data)
#
# this function removes the target file system object.
#
def Remove(target):
entries = None
entry = None
if os.path.isfile(target) or os.path.islink(target):
os.unlink(target)
if os.path.isdir(target):
entries = os.listdir(target)
for entry in entries:
Remove(target + "/" + entry)
os.rmdir(target)
#
# this function writes data to a file.
#
def Push(content, path):
handle = None
handle = open(path, "w")
handle.write(content)
handle.close()
#
# this function reads data from a file.
#
def Pull(path):
handle = None
line = None
if not os.path.exists(path):
return None
try:
handle = open(path, "r")
except IOError:
return None
content = str()
for line in handle.readlines():
content += line
handle.close()
if len(content) == 0:
content = None
return content
#
# this function creates a temporary file or directory.
#
def Temporary(option):
location = None
if option == OptionFile:
tuple = tempfile.mkstemp()
os.close(tuple[0])
location = tuple[1]
elif option == OptionDirectory:
location = tempfile.mkdtemp()
return location
#
# this function copies one file to another target.
#
def Copy(path, target):
shutil.copy(path, target)
#
# this function searches for file names matching the given pattern.
#
def Search(directory, pattern, options):
elements = []
entries = None
entry = None
entries = os.listdir(directory)
for entry in entries:
if (options & OptionFile) and \
(os.path.isfile(directory + "/" + entry)) and \
(re.search(pattern, entry)):
elements += [ directory + "/" + entry ]
if (os.path.isdir(directory + "/" + entry)):
if (options & OptionDirectory) and \
(re.search(pattern, entry)):
elements += [ directory + "/" + entry ]
if (options & OptionRecursive) and \
(not os.path.islink(directory + "/" + entry)):
elements += Search(directory + "/" + entry, pattern, options)
return elements
#
# this function creates the directories up to the destination path.
#
def Dig(target):
path = None
steps = None
step = None
if target[0] == "/":
path = "/"
steps = os.path.dirname(target).strip("/").split("/")
for step in steps:
if not path:
path = step
else:
path = path + "/" + step
if not os.path.exists(path):
os.mkdir(path)
#
# this function transfers the content from one file to the other.
#
def Transfer(source, destination):
input = None
output = None
line = None
try:
input = open(source, "r")
output = open(destination, "a")
except IOError:
return None
line = input.read(256)
output.write(line)
output.close()
input.close()
def Email(source,
destination,
subject,
body,
attachment = None):
capability = None
content = None
configuration = None
message = None
stream = None
report = None
status = None
output = None
emails = None
a = None
# create a temporary file.
configuration = ktp.miscellaneous.Temporary(ktp.miscellaneous.OptionFile)
# create a configuration file.
content = """\
set realname = "%(from)s"
set from = "%(from)s"
set use_from = yes\
""" % { "from": source }
# store the temporary mutt configuration file.
ktp.miscellaneous.Push(content, configuration)
# create a temporary file.
message = ktp.miscellaneous.Temporary(ktp.miscellaneous.OptionFile)
# prepare the -a option depending on the presence of an attachment.
if attachment:
a = [ "-a", attachment ]
else:
a = []
# store the temporary message.
ktp.miscellaneous.Push(body, message)
# create a stream file.
stream = ktp.miscellaneous.Temporary(ktp.miscellaneous.OptionFile)
# email the capability to the supposed recipient.
status = ktp.process.Invoke("mutt",
a +
[ "-F", configuration,
"-s", subject,
" ".join(destination),
"<" + message ])
# retrieve the output.
output = ktp.miscellaneous.Pull(stream)
# remove the stream file.
ktp.miscellaneous.Remove(stream)
# remove the temporary files.
ktp.miscellaneous.Remove(message)
ktp.miscellaneous.Remove(configuration)
#
# this function transforms a Python data structure into a string
# representation.
#
def Stringify(data, margin = "", alignment = 26):
string = str()
key = None
length = None
if isinstance(data, dict):
for key in data:
if not isinstance(data[key], dict) and not isinstance(data[key], list):
length = len(margin) + len(str(key)) + 1
string += margin + str(key) + ":" + \
(alignment - length) * " " + str(data[key]) + "\n"
else:
string += margin + str(key) + ":" + "\n"
string += Stringify(data[key], margin + " ", alignment)
elif isinstance(data, list):
for element in data:
string += Stringify(element, margin, alignment)
else:
string += alignment * " " + str(data) + "\n"
return string

View file

@ -0,0 +1,173 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANE...TEST-SYSTEM/test/packages/ktp/process.py
#
# created julien quintard [mon oct 25 20:54:05 2010]
# updated julien quintard [thu nov 4 14:40:44 2010]
#
#
# ---------- packages ---------------------------------------------------------
#
import subprocess
import os
import miscellaneous
import ktp
#
# ---------- definitions ------------------------------------------------------
#
OptionNone = 0
OptionBackground = 1
#
# ---------- functions --------------------------------------------------------
#
#
# this function invokes a sub-process and returns either the status or a
# monitor if the invocation has been performed in background.
#
def Invoke(command,
arguments,
stream = None,
option = OptionNone):
info = None
directory = None
file = None
handle = None
descriptor = None
status = None
output = None
error = None
# retrive file information.
info = os.path.split(command)
directory = info[0]
file = info[1]
# change directory if required.
if directory:
wd = os.getcwd()
os.chdir(directory)
# set up the stdout and stderr, according to the given stream file.
if stream:
# open the stream file.
descriptor = os.open(stream, os.O_CREAT | os.O_TRUNC | os.O_WRONLY)
# set the output and error descriptors.
output = descriptor
error = subprocess.STDOUT
else:
# open the null stream file.
descriptor = os.open(os.devnull, os.O_WRONLY)
# set the output and error descriptors so that to ignore everything.
output = descriptor
error = subprocess.STDOUT
# launch the command.
handle = subprocess.Popen(command + " " + " ".join(arguments),
stdout = output,
stderr = error,
shell = True)
# come back to the original directory if necessary.
if directory:
os.chdir(wd)
# return information according to the option.
if option == OptionBackground:
return (handle, stream, descriptor)
else:
# wait for the process to terminate.
status = handle.wait()
# close the descriptor.
if descriptor:
os.close(descriptor)
if status != 0:
return (ktp.StatusError)
else:
return (ktp.StatusOk)
#
# this function waits for a process to terminate and return the status.
#
def Wait(monitor):
handle = None
stream = None
descriptor = None
status = None
# retrieve the information.
(handle, stream, descriptor) = monitor
# wait for the process to terminate.
status = handle.wait()
# close the descriptor.
if descriptor:
os.close(descriptor)
if status != 0:
return (ktp.StatusError)
else:
return (ktp.StatusOk)
#
# this function probes a process.
#
def Probe(monitor):
handle = None
stream = None
descriptor = None
status = None
# retrieve the information.
(handle, stream, descriptor) = monitor
# probe the process.
status = handle.poll()
if isinstance(status, int):
# close the descriptor.
if descriptor:
os.close(descriptor)
if status != 0:
return (ktp.StatusError)
else:
return (ktp.StatusOk)
else:
return (ktp.StatusUnknown)
#
# this function terminates a process by killing it.
#
def Terminate(monitor):
handle = None
stream = None
descriptor = None
status = None
# retrieve the information.
(handle, stream, descriptor) = monitor
# kill the process.
handle.kill()
# close the descriptor.
if descriptor:
os.close(descriptor)

View file

@ -0,0 +1,59 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/queue.py
#
# created julien quintard [mon oct 25 19:58:10 2010]
# updated julien quintard [wed feb 2 20:59:25 2011]
#
#
# ---------- packages ---------------------------------------------------------
#
import os
import ktp
#
# ---------- functions --------------------------------------------------------
#
#
# this function adds an identifier to the queue.
#
def Push(directory,
identifier):
handle = None
path = None
path = directory + "/" + identifier
ktp.miscellaneous.Push("",
path)
#
# this function returns the next queue'd identifier, or None if none.
#
def Pop(directory):
identifier = None
entries = None
entry = None
path = None
entries = os.listdir(directory)
for entry in entries:
path = directory + "/" + entry
identifier = entry
ktp.miscellaneous.Remove(path)
return identifier
return None

View file

@ -0,0 +1,67 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/report.py
#
# created julien quintard [tue oct 26 11:12:10 2010]
# updated julien quintard [wed feb 2 14:41:38 2011]
#
#
# ---------- packages ---------------------------------------------------------
#
import yaml
import os
import re
import miscellaneous
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".rpt"
StateInProgress = "in progress"
StateDone = "done"
#
# ---------- functions --------------------------------------------------------
#
#
# this function returns a list of report identifiers.
#
def List(directory):
reports = []
entries = None
entry = None
path = None
entries = os.listdir(directory)
for entry in entries:
path = directory + "/" + entry
if os.path.isfile(path) and re.search("^.*" + Extension + "$", path):
reports += [ entry[:-len(Extension)] ]
return reports
#
# this function stores a report.
#
def Store(report, path):
yaml.dump(report,
file(path, 'w'))
#
# this function loads a report.
#
def Load(path):
return yaml.load(file(path, 'r'))

View file

@ -0,0 +1,18 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/snapshot.py
#
# created julien quintard [wed oct 27 14:09:12 2010]
# updated julien quintard [wed oct 27 14:09:21 2010]
#
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".snp"

View file

@ -0,0 +1,62 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/stage.py
#
# created julien quintard [mon oct 25 20:23:05 2010]
# updated julien quintard [sun dec 5 22:15:02 2010]
#
#
# ---------- packages ---------------------------------------------------------
#
import yaml
import os
import re
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".stg"
#
# ---------- functions --------------------------------------------------------
#
#
# this function returns a list of stage identifiers.
#
def List(directory):
stages = []
entries = None
entry = None
path = None
entries = os.listdir(directory)
for entry in entries:
path = directory + "/" + entry
if os.path.isfile(path) and re.search("^.*" + Extension + "$", path):
stages += [ entry[:-len(Extension)] ]
return stages
#
# this function stores a stage.
#
def Store(stage, path):
yaml.dump(stage,
file(path, 'w'))
#
# this function loads a stage.
#
def Load(path):
return yaml.load(file(path, 'r'))

View file

@ -0,0 +1,62 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/statement.py
#
# created julien quintard [mon oct 25 20:23:05 2010]
# updated julien quintard [mon dec 6 07:45:36 2010]
#
#
# ---------- packages ---------------------------------------------------------
#
import yaml
import os
import re
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".stm"
#
# ---------- functions --------------------------------------------------------
#
#
# this function returns a list of statement identifiers.
#
def List(directory):
statements = []
entries = None
entry = None
path = None
entries = os.listdir(directory)
for entry in entries:
path = directory + "/" + entry
if os.path.isfile(path) and re.search("^.*" + Extension + "$", path):
statements += [ entry[:-len(Extension)] ]
return statements
#
# this function stores a statement.
#
def Store(statement, path):
yaml.dump(statement,
file(path, 'w'))
#
# this function loads a statement.
#
def Load(path):
return yaml.load(file(path, 'r'))

106
test/packages/ktp/suite.py Normal file
View file

@ -0,0 +1,106 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/packages/ktp/suite.py
#
# created julien quintard [wed oct 27 10:53:58 2010]
# updated julien quintard [tue dec 7 15:09:17 2010]
#
#
# ---------- packages ---------------------------------------------------------
#
import yaml
import os
import re
import sys
TestDirectory = os.path.abspath(os.path.dirname( \
os.path.realpath(sys.argv[0])) + "/..")
sys.path.append(TestDirectory + "/packages")
import ktp
#
# ---------- definitions ------------------------------------------------------
#
Extension = ".suite"
TestsDirectory = TestDirectory + "/tests"
#
# ---------- functions --------------------------------------------------------
#
#
# this function returns a list of suite identifiers.
#
def List(directory):
suites = []
entries = None
entry = None
path = None
entries = os.listdir(directory)
for entry in entries:
path = directory + "/" + entry
if os.path.isfile(path) and re.search("^.*" + Extension + "$", path):
suites += [ entry[:-len(Extension)] ]
return suites
#
# this function loads a suite.
#
def Load(path):
return yaml.load(file(path, 'r'))
#
# this function loads all the manifests belonging to the given suite in
# a dictionary.
#
def Manifests(suite):
manifests = {}
component = None
name = None
location = None
paths = None
path = None
manifest = None
test = None
# load the manifests.
if "components" in suite:
for component in suite["components"]:
for location in suite["components"][component]:
# search for manifest files.
paths = ktp.miscellaneous.Search(TestsDirectory + "/" + \
location,
"^.*\.mnf$",
ktp.miscellaneous.OptionFile |
ktp.miscellaneous.OptionRecursive)
for path in paths:
# load the manifest.
manifest = ktp.manifest.Load(path)
# compute the proper name according to the defined component:
# for instance, given the "segment" component, the test name
# segment/permissions/01 will be transformed into permissions/01
if component == manifest["name"][:len(component)]:
test = manifest["name"][len(component) + 1:]
else:
test = manifest["name"]
manifests[test] = manifest
return manifests

View file

@ -0,0 +1,46 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/KANETON-TEST-SYSTEM/server/ktp/trace.py
#
# created julien quintard [mon oct 25 20:46:33 2010]
# updated julien quintard [tue oct 26 15:42:17 2010]
#
#
# ---------- packages ---------------------------------------------------------
#
import traceback
import miscellaneous
#
# ---------- functions --------------------------------------------------------
#
#
# this function generates a stack trace.
#
def Generate():
temporary = None
trace = None
# create a temporary file.
temporary = miscellaneous.Temporary(miscellaneous.OptionFile)
# put the trace in the temporary file.
traceback.print_exc(None, file(temporary, 'w'))
# read the file.
trace = miscellaneous.Pull(temporary)
# remove the temporary file.
miscellaneous.Remove(temporary)
# return the trace.
return trace

View file

@ -0,0 +1,60 @@
#
# ---------- header -----------------------------------------------------------
#
# project kaneton
#
# license kaneton
#
# file /home/mycure/kaneton/test/packages/ktp/xmlrpc.py
#
# created julien quintard [mon oct 25 19:44:10 2010]
# updated julien quintard [tue feb 8 17:39:08 2011]
#
#
# ---------- packages ---------------------------------------------------------
#
import xmlrpclib
import sys
import ktp
#
# ---------- functions --------------------------------------------------------
#
#
# this method wraps a call to a remote method.
#
def Call(value):
type = None
data = None
# retrieve the type.
type = value[0]
# transform the data should it be in binary form.
if isinstance(value[1], xmlrpclib.Binary) == True:
data = str(value[1])
else:
data = value[1]
# display an error if the type indicates so.
if type == ktp.StatusError:
print("[error] " + data)
sys.exit(42)
return data
#
# this method connects to an XMLRPC server.
#
def Connect(server):
handle = None
# issue the connection request.
handle = xmlrpclib.Server(server,
allow_none = True)
return handle