Documentation
¶
Overview ¶
Package test161 implements a library for testing OS/161 kernels. We use expect to drive the sys161 system simulator and collect useful output using the stat socket.
Index ¶
- Constants
- Variables
- func GetDeployKeySSHCmd(users []string, keyDir string) string
- func KeyGen(email, token string, env *TestEnvironment) (string, error)
- func ManagerCapacity() uint
- func SetManagerCapacity(capacity uint)
- func StartManager()
- func StopManager()
- type BuildCommand
- type BuildConf
- type BuildResults
- type BuildTest
- type Command
- type CommandConf
- type CommandTemplate
- type CommandTemplates
- type DependencyRunner
- type DiskConf
- type DoNothingPersistence
- type ExpectedOutputLine
- type GroupConfig
- type GroupStat
- type InputLine
- type Limits
- type ManagerStats
- type MiscConf
- type MongoPersistence
- type MonitorConf
- type OutputLine
- type PersistenceManager
- type ProgramVersion
- type RequestKeyResonse
- type SimpleRunner
- type Stat
- type StatConf
- type StatsByName
- type Status
- type Student
- type Submission
- type SubmissionManager
- func (sm *SubmissionManager) CombinedStats() *Test161Stats
- func (sm *SubmissionManager) Pause()
- func (sm *SubmissionManager) Resume()
- func (sm *SubmissionManager) Run(s *Submission) error
- func (sm *SubmissionManager) SetStaffOnly()
- func (sm *SubmissionManager) Stats() *ManagerStats
- func (sm *SubmissionManager) Status() int
- type SubmissionRequest
- type SubmissionUserInfo
- type Sys161Conf
- type TagDescription
- type TagDescriptions
- type TagMap
- type Target
- type TargetCommand
- type TargetList
- type TargetListItem
- type TargetStats
- type TargetTest
- type TemplOutputLine
- type Test
- func (t *Test) Close(time.Time)
- func (t *Test) ExpectCall(time.Time, *regexp.Regexp)
- func (t *Test) ExpectReturn(time.Time, expect.Match, error)
- func (t *Test) Key() string
- func (t *Test) MergeAllDefaults() error
- func (t *Test) MergeConf(defaults Test) error
- func (t *Test) OutputJSON() (string, error)
- func (t *Test) OutputString() string
- func (t *Test) PrintConf() (string, error)
- func (t *Test) Recv(receivedTime time.Time, received []byte)
- func (t *Test) RecvEOF(time.Time)
- func (t *Test) RecvNet(time.Time, []byte)
- func (t *Test) Run(env *TestEnvironment) (err error)
- func (t *Test) Send(time.Time, []byte)
- func (t *Test) SendMasked(time.Time, []byte)
- func (t *Test) SetEnv(env *TestEnvironment)
- type Test161JobResult
- type Test161Stats
- type TestEnvironment
- type TestGroup
- type TestResult
- type TestRunner
- type TestStat
- type TestUpdateMsg
- type TestingPersistence
- type TimeFixedPoint
- type UploadRequest
- type UsageStat
Constants ¶
const ( CMD_OPT_NO = "no" CMD_OPT_MAYBE = "maybe" CMD_OPT_YES = "yes" )
Command options for panics and timesout
const ( SM_ACCEPTING = iota SM_NOT_ACCEPTING SM_STAFF_ONLY )
const ( COLLECTION_SUBMISSIONS = "submissions" COLLECTION_TESTS = "tests" COLLECTION_STUDENTS = "students" COLLECTION_TARGETS = "targets" COLLECTION_USERS = "users" COLLECTION_USAGE = "usage" )
const ( MSG_PERSIST_CREATE = iota // The object has been created MSG_PERSIST_UPDATE // Generic update message. MSG_PERSIST_OUTPUT // Added an output line (command types only) MSG_PERSIST_COMPLETE // We won't update the object any more MSG_TARGET_LOAD // When a target is loaded )
const ( MSG_FIELD_SCORE = 1 << iota MSG_FIELD_STATUS MSG_FIELD_TESTS MSG_FIELD_OUTPUT MSG_FIELD_STATUSES )
Inidividual field updates
const ( PERSIST_TYPE_STUDENTS = 1 << iota PERSIST_TYPE_USERS )
const ( UpdateReasonOutput = iota UpdateReasonScore UpdateReasonCommandDone )
const ( COMMAND_STATUS_NONE = "none" // The command has not yet run COMMAND_STATUS_RUNNING = "running" // The command is running COMMAND_STATUS_CORRECT = "correct" // The command produced the expected output and did not crash COMMAND_STATUS_INCORRECT = "incorrect" // The command received some partial credit )
Statuses for commands
const ( SUBMISSION_SUBMITTED = "submitted" // Submitted and queued SUBMISSION_BUILDING = "building" // Building the kernel SUBMISSION_RUNNING = "running" // The tests started running SUBMISSION_ABORTED = "aborted" // Aborted because one or more tests failed to error SUBMISSION_COMPLETED = "completed" // Completed )
const ( TARGET_ASST = "asst" TARGET_PERF = "perf" )
const ( TEST_SCORING_ENTIRE = "entire" TEST_SCORING_PARTIAL = "partial" )
const CUR_USAGE_VERSION = 1
const CollabMsgAsst1 = `` /* 723-byte string literal not displayed */
const CollabMsgAsst2 = `` /* 1149-byte string literal not displayed */
const CollabMsgAsst3 = `` /* 881-byte string literal not displayed */
const DEFAULT_MGR_CAPACITY uint = 0
const KEYBYTES = 32
const MAX_EXPANSION_LOOPS = 1024
const MAX_RETRY_LOOPS = 16
const SYS161_TEMPLATE = `` /* 406-byte string literal not displayed */
const (
UPLOAD_TYPE_USAGE = iota
)
Variables ¶
var CONF_DEFAULTS = Test{ Sys161: Sys161Conf{ Path: "sys161", CPUs: 8, RAM: "1M", Disk1: DiskConf{ Enabled: "false", Bytes: "32M", RPM: 7200, NoDoom: "true", }, Disk2: DiskConf{ Enabled: "false", Bytes: "32M", RPM: 7200, NoDoom: "false", }, }, Stat: StatConf{ Resolution: 0.01, Window: 1, }, Monitor: MonitorConf{ Enabled: "true", Window: 400, Kernel: Limits{ EnableMin: "false", Min: 0.001, Max: 1.0, }, User: Limits{ EnableMin: "false", Min: 0.0001, Max: 1.0, }, ProgressTimeout: 10.0, CommandTimeout: 60.0, }, Misc: MiscConf{ CommandRetries: 5, PromptTimeout: 1800.0, CharacterTimeout: 1000, RetryCharacters: "true", KillOnExit: "false", }, }
var KERNEL_COMMAND_CONF = &CommandConf{
Prompt: `OS/161 kernel [? for menu]: `,
End: "q",
}
var SHELL_COMMAND_CONF = &CommandConf{
Prefix: "$",
Prompt: `OS/161$ `,
Start: "s",
End: "exit",
}
var Version = ProgramVersion{
Major: 1,
Minor: 3,
Revision: 2,
}
Functions ¶
func GetDeployKeySSHCmd ¶
func KeyGen ¶
func KeyGen(email, token string, env *TestEnvironment) (string, error)
On success, KeyGen returns the public key of the newly generated public/private key pair
func ManagerCapacity ¶
func ManagerCapacity() uint
func SetManagerCapacity ¶
func SetManagerCapacity(capacity uint)
Types ¶
type BuildCommand ¶
type BuildCommand struct { ID string `yaml:"-" json:"id" bson:"_id,omitempty"` Type string `json:"type"` Input InputLine `json:"input"` // Set during target init PointsAvailable uint `json:"points_avail" bson:"points_avail"` PointsEarned uint `json:"points_earned" bson:"points_earned"` // Set during testing Output []*OutputLine `json:"output"` // Set during evaluation Status string `json:"status"` // contains filtered or unexported fields }
A variant of a Test Command for builds
func (*BuildCommand) Run ¶
func (cmd *BuildCommand) Run(env *TestEnvironment) error
Execute an individual BuildTest command
type BuildConf ¶
type BuildConf struct { Repo string // The git repository to clone CommitID string // The git commit id (HEAD, hash, etc.) to check out KConfig string // The os161 kernel config file for the build RequiredCommit string // A commit required to be in git log CacheDir string // Cache for previous builds RequiresUserland bool // Does userland need to be built? Overlay string // The overlay to use (append to overlay dir in env) Users []string // The users who own the repo. Needed for the finding the key. }
BuildConf specifies the configuration for building os161.
func (*BuildConf) ToBuildTest ¶
func (b *BuildConf) ToBuildTest(env *TestEnvironment) (*BuildTest, error)
Use the BuildConf to create a sequence of commands that will build an os161 kernel and userspace binaries (ASST2+).
type BuildResults ¶
type BuildTest ¶
type BuildTest struct { // Mongo ID ID string `yaml:"-" json:"id" bson:"_id,omitempty"` // ID of the submission this test belongs to. SubmissionID string `yaml:"-" json:"-" bson:"submission_id"` // Metadata Name string `yaml:"name" json:"name"` Description string `yaml:"description" json:"description"` Commands []*BuildCommand `json:"commands"` // Protected by L Status []Status `json:"status"` // Protected by L Result TestResult `json:"result"` // Protected by L // Dependency data DependencyID string `json:"depid"` IsDependency bool `json:"isdependency"` // Grading. These are set when the test is being run as part of a Target. PointsAvailable uint `json:"points_avail" bson:"points_avail"` PointsEarned uint `json:"points_earned" bson:"points_earned"` ScoringMethod string `json:"scoring_method" bson:"scoring_method"` // contains filtered or unexported fields }
BuildTest is a variant of a Test, and specifies how the build process should work. We obey the same schema so the front end tools can treat this like any other test.
func (*BuildTest) OutputJSON ¶
func (*BuildTest) Run ¶
func (t *BuildTest) Run(env *TestEnvironment) (*BuildResults, error)
Run builds the OS/161 kernel and userspace binaries
type Command ¶
type Command struct { // Mongo ID ID string `yaml:"-" json:"id" bson:"_id,omitempty"` // Set during init Type string `json:"type"` PromptPattern *regexp.Regexp `json:"-" bson:"-"` Input InputLine `json:"input"` Config CommandTemplate `json:"config"` // Set during target init PointsAvailable uint `json:"points_avail" bson:"points_avail"` PointsEarned uint `json:"points_earned" bson:"points_earned"` // Set during run init Panic string `json:"panic"` Timeout float32 `json:"timeout"` TimesOut string `json:"timesout"` ExpectedOutput []*ExpectedOutputLine // Set during testing Output []*OutputLine `json:"output"` SummaryStats Stat `json:"summarystats"` AllStats []Stat `json:"stats"` StartTime TimeFixedPoint `json:"starttime"` EndTime TimeFixedPoint `json:"endtime"` TimedOut bool `json:"timedout"` // Set during evaluation Status string `json:"status"` // Backwards pointer to the Test. This needs to be public for printing Test *Test `json:"-" bson:"-"` }
func (*Command) Instantiate ¶
func (c *Command) Instantiate(env *TestEnvironment) error
Instantiate the command (input, expected output) using the command template. This needs to be must be done prior to executing the command.
type CommandConf ¶
type CommandTemplate ¶
type CommandTemplate struct { Name string `yaml:"name"` Output []*TemplOutputLine `yaml:"output"` Input []string `yaml:"input"` Panic string `yaml:"panics"` // CMD_OPT TimesOut string `yaml:"timesout"` // CMD_OPT Timeout float32 `yaml:"timeout"` // Timeout in sec. A timeout of 0.0 uses the test default. }
Template for commands instances. These get expanded depending on the command environment.
func (*CommandTemplate) Clone ¶
func (ct *CommandTemplate) Clone() *CommandTemplate
type CommandTemplates ¶
type CommandTemplates struct {
Templates []*CommandTemplate `yaml:"templates"`
}
CommandTemplate Collection. We just use this for loading and move the references into a map in the global environment.
func CommandTemplatesFromFile ¶
func CommandTemplatesFromFile(file string) (*CommandTemplates, error)
func CommandTemplatesFromString ¶
func CommandTemplatesFromString(text string) (*CommandTemplates, error)
type DependencyRunner ¶
type DependencyRunner struct {
// contains filtered or unexported fields
}
This runner has mad respect for dependencies.
func (*DependencyRunner) Group ¶
func (r *DependencyRunner) Group() *TestGroup
func (*DependencyRunner) Run ¶
func (r *DependencyRunner) Run() <-chan *Test161JobResult
type DoNothingPersistence ¶
type DoNothingPersistence struct { }
func (*DoNothingPersistence) CanRetrieve ¶
func (d *DoNothingPersistence) CanRetrieve() bool
func (*DoNothingPersistence) Close ¶
func (d *DoNothingPersistence) Close()
func (*DoNothingPersistence) Notify ¶
func (d *DoNothingPersistence) Notify(entity interface{}, msg, what int) error
type ExpectedOutputLine ¶
Command instance expected output line. The difference here is that we store the name of the key that we need to verify the output.
type GroupConfig ¶
type GroupConfig struct { Name string `json:"name"` UseDeps bool `json:"usedeps"` Tests []string `json:"tests"` Env *TestEnvironment `json:"-" bson:"-"` }
GroupConfig specifies how a group of tests should be created and run.
type GroupStat ¶
type GroupStat struct { TargetTagName string `bson:"target_tag_name" json:"target_tag_name"` PointsAvailable uint `bson:"max_score" json:"max_score"` Status string `bson:"status" json:"status"` Score uint `bson:"score" json:"score"` Tests []*TestStat `bson:"tests" json:"tests"` Errors []string `bson:"errors" json:"errors"` SubmissionTime time.Time `bson:"submission_time" json:"submission_time"` CompletionTime time.Time `bson:"completion_time" json:"completion_time"` }
type InputLine ¶
type InputLine struct { WallTime TimeFixedPoint `json:"walltime"` SimTime TimeFixedPoint `json:"simtime"` Line string `json:"line"` }
type ManagerStats ¶
type ManagerStats struct { // protected by manager.L Running uint `json:"running"` HighRunning uint `json:"high_running"` Queued uint `json:"queued"` HighQueued uint `json:"high_queued"` Finished uint `json:"finished"` MaxWait int64 `json:"max_wait_ms"` AvgWait int64 `json:"avg_wait_ms"` StartTime time.Time // contains filtered or unexported fields }
func GetManagerStats ¶
func GetManagerStats() *ManagerStats
Return a copy of the current shared test manager stats
type MiscConf ¶
type MiscConf struct { CommandRetries uint `yaml:"commandretries" json:"commandretries"` PromptTimeout float32 `yaml:"prompttimeout" json:"prompttimeout"` CharacterTimeout uint `yaml:"charactertimeout" json:"charactertimeout"` TempDir string `yaml:"tempdir" json:"-" bson:"-"` RetryCharacters string `yaml:"retrycharacters" json:"retrycharacters"` KillOnExit string `yaml:"killonexit" json:"killonexit"` }
type MongoPersistence ¶
type MongoPersistence struct {
// contains filtered or unexported fields
}
func (*MongoPersistence) CanRetrieve ¶
func (m *MongoPersistence) CanRetrieve() bool
func (*MongoPersistence) Close ¶
func (m *MongoPersistence) Close()
func (*MongoPersistence) Notify ¶
func (m *MongoPersistence) Notify(t interface{}, msg, what int) (err error)
type MonitorConf ¶
type MonitorConf struct { Enabled string `yaml:"enabled" json:"enabled"` Window uint `yaml:"window" json:"window"` Kernel Limits `yaml:"kernel" json:"kernel"` User Limits `yaml:"user" json:"user"` ProgressTimeout float32 `yaml:"progresstimeout" json:"progresstimeout"` CommandTimeout float32 `yaml:"commandtimeout" json:"commandtimeout"` }
type OutputLine ¶
type OutputLine struct { WallTime TimeFixedPoint `json:"walltime"` SimTime TimeFixedPoint `json:"simtime"` Buffer bytes.Buffer `json:"-" bson:"-"` Line string `json:"line"` Trusted bool `json:"trusted"` KeyName string `json:"keyname"` }
type PersistenceManager ¶
type PersistenceManager interface { Close() Notify(entity interface{}, msg, what int) error CanRetrieve() bool // what should be PERSIST_TYPE_* // who is a map of field:value // res is where to deserialize the data Retrieve(what int, who map[string]interface{}, filter map[string]interface{}, res interface{}) error }
Each Submission has at most one PersistenceManager, and it is pinged when a variety of events occur. These callbacks are invoked synchronously, so it's up to the PersistenceManager to not slow down the tests. We do this because the PersistenceManager can create goroutines if applicable, but we can't make an asynchronous call synchronous when it might be needed. So, be kind ye PersistenceManagers.
func NewMongoPersistence ¶
func NewMongoPersistence(dial *mgo.DialInfo) (PersistenceManager, error)
type ProgramVersion ¶
type ProgramVersion struct { Major uint `yaml:"major"` Minor uint `yaml:"minor"` Revision uint `yaml:"revision"` }
func (ProgramVersion) CompareTo ¶
func (this ProgramVersion) CompareTo(other ProgramVersion) int
Returns 1 if this > other, 0 if this == other, and -1 if this < other
func (ProgramVersion) String ¶
func (v ProgramVersion) String() string
type RequestKeyResonse ¶
RequestKeyResonse is the repsonse we send back during validation if the keys aren't up-to-date.
type SimpleRunner ¶
type SimpleRunner struct {
// contains filtered or unexported fields
}
A simple runner that tries to run everything as fast as it's allowed to, i.e. it doesn't care about dependencies.
func (*SimpleRunner) Group ¶
func (r *SimpleRunner) Group() *TestGroup
func (*SimpleRunner) Run ¶
func (r *SimpleRunner) Run() <-chan *Test161JobResult
type Stat ¶
type Stat struct { Start TimeFixedPoint `json:"start"` End TimeFixedPoint `json:"end"` Length TimeFixedPoint `json:"length"` Count uint `json:"count"` WallStart TimeFixedPoint `json:"wallstart"` WallEnd TimeFixedPoint `json:"wallend"` WallLength TimeFixedPoint `json:"walllength"` // Read from stat line Nsec uint64 `json:"-" bson:"-"` Kinsns uint32 `json:"kinsns"` Uinsns uint32 `json:"uinsns"` Udud uint32 `json:"udud"` Idle uint32 `json:"idle"` IRQs uint32 `json:"irqs"` Exns uint32 `json:"exns"` Disk uint32 `json:"disk"` Con uint32 `json:"con"` Emu uint32 `json:"emu"` Net uint32 `json:"net"` // Derived Insns uint32 `json:"insns"` // contains filtered or unexported fields }
type StatsByName ¶
type StatsByName []*TargetStats
Target stats sorting
func (StatsByName) Len ¶
func (a StatsByName) Len() int
func (StatsByName) Less ¶
func (a StatsByName) Less(i, j int) bool
func (StatsByName) Swap ¶
func (a StatsByName) Swap(i, j int)
type Status ¶
type Status struct { WallTime TimeFixedPoint `json:"walltime"` SimTime TimeFixedPoint `json:"simtime"` Status string `json:"status"` Message string `json:"message"` }
type Student ¶
type Submission ¶
type Submission struct { // Configuration ID string `bson:"_id,omitempty"` Users []string `bson:"users"` Repository string `bson:"repository"` CommitID string `bson:"commit_id"` CommitRef string `bson:"commit_ref"` // Just informational ClientVersion string `bson:"client_version"` // Just informational // From the environment OverlayCommitID string `bson:"overlay_commit_id"` // Just informational IsStaff bool `bson:"is_staff"` // Target details TargetID string `bson:"target_id"` TargetName string `bson:"target_name"` TargetVersion uint `bson:"target_version"` IsMetaTarget bool `bson:"is_meta_target"` // Submitted target, which is different from target details if submitting // to a subtarget of a metatarget. SubmittedTargetID string `bson:"submitted_target_id"` SubmittedTargetName string `bson:"submitted_target_name"` SubmittedTargetVersion uint `bson:"submitted_target_version"` PointsAvailable uint `bson:"max_score"` TargetType string `bson:"target_type"` // Results Status string `bson:"status"` Score uint `bson:"score"` Performance float64 `bson:"performance"` TestIDs []string `bson:"tests"` Errors []string `bson:"errors"` EstimatedScore uint `bson:"estimated_score"` SubmissionTime time.Time `bson:"submission_time"` CompletionTime time.Time `bson:"completion_time"` Env *TestEnvironment `bson:"-" json:"-"` BuildTest *BuildTest `bson:"-" json:"-"` Tests *TestGroup `bson:"-" json:"-"` // Split information for meta/sub-targets. We store IDs for // mongo/persistence, and keep references around in case we need them, // and for testing. OrigSubmissionID string `bson:"orig_submission_id"` SubSubmissionIDs []string `bson:"sub_submission_ids"` // contains filtered or unexported fields }
func NewSubmission ¶
func NewSubmission(request *SubmissionRequest, origenv *TestEnvironment) (*Submission, []error)
Create a new Submission that can be evaluated by the test161 server or client.
This submission has a copy of the test environment, so it's safe to pass the same enviromnent for multiple submissions. Local fields will be set accordingly.
func (*Submission) TargetStats ¶
func (s *Submission) TargetStats() (result *TargetStats)
type SubmissionManager ¶
type SubmissionManager struct {
// contains filtered or unexported fields
}
func NewSubmissionManager ¶
func NewSubmissionManager(env *TestEnvironment) *SubmissionManager
func (*SubmissionManager) CombinedStats ¶
func (sm *SubmissionManager) CombinedStats() *Test161Stats
func (*SubmissionManager) Pause ¶
func (sm *SubmissionManager) Pause()
func (*SubmissionManager) Resume ¶
func (sm *SubmissionManager) Resume()
func (*SubmissionManager) Run ¶
func (sm *SubmissionManager) Run(s *Submission) error
func (*SubmissionManager) SetStaffOnly ¶
func (sm *SubmissionManager) SetStaffOnly()
func (*SubmissionManager) Stats ¶
func (sm *SubmissionManager) Stats() *ManagerStats
func (*SubmissionManager) Status ¶
func (sm *SubmissionManager) Status() int
type SubmissionRequest ¶
type SubmissionRequest struct { Target string // Name of the target Users []*SubmissionUserInfo // Email addresses of users Repository string // Git repository to clone CommitID string // Git commit id to checkout after cloning CommitRef string // The ref they're submitting with, if one is set ClientVersion ProgramVersion // The version of test161 the client is running EstimatedScores map[string]uint // The local score test161 computed }
SubmissionRequests are created by clients and used to generate Submissions. A SubmissionRequest represents the data required to run a test161 target for evaluation by the test161 server.
func (*SubmissionRequest) CheckUserKeys ¶
func (req *SubmissionRequest) CheckUserKeys(env *TestEnvironment) []*RequestKeyResonse
Check if the local copy of the key is up-to-date. Return an empty key if the user's key has not been created, or the new key if the hash is different.
func (*SubmissionRequest) Validate ¶
func (req *SubmissionRequest) Validate(env *TestEnvironment) ([]*Student, error)
type SubmissionUserInfo ¶
type Sys161Conf ¶
type TagDescription ¶
type TagDescriptions ¶
type TagDescriptions struct {
Tags []*TagDescription `yaml:"tags"`
}
TagDescription Collection. We just use this for loading and move the references into a map in the global environment.
func TagDescriptionsFromFile ¶
func TagDescriptionsFromFile(file string) (*TagDescriptions, error)
func TagDescriptionsFromString ¶
func TagDescriptionsFromString(text string) (*TagDescriptions, error)
type TagMap ¶
TagMap stores Tests indexed by id and maintains a map of tag -> tests for the test set.
type Target ¶
type Target struct { // Make sure to update isChangeAllowed with any new fields that need to be versioned. ID string `yaml:"-" bson:"_id"` Name string `yaml:"name"` Active string `yaml:"active"` Version uint `yaml:"version"` Type string `yaml:"type"` Points uint `yaml:"points"` KConfig string `yaml:"kconfig"` RequiredCommit string `yaml:"required_commit" bson:"required_commit"` RequiresUserland bool `yaml:"userland" bson:"userland"` Tests []*TargetTest `yaml:"tests"` FileHash string `yaml:"-" bson:"file_hash"` FileName string `yaml:"-" bson:"file_name"` // MetaTarget info IsMetaTarget bool `yaml:"is_meta_target" bson:"is_meta_target"` SubTargetNames []string `yaml:"sub_target_names" bson:"sub_target_names"` MetaName string `yaml:"meta_name"` // Front-end only PrintName string `yaml:"print_name" bson:"print_name"` Description string `yaml:"description"` Link string `yaml:"link" bson:"link"` Leaderboard string `yaml:"leaderboard" bson:"leaderboard"` // contains filtered or unexported fields }
A test161 Target is the sepcification for group of related tests. Currently, we support two types of Targets with special meaning: asst and perf. The main difference between Targets and TestGroups is that Targets can have a scoring component, either points or performance. The test161 submission system operates in terms of Targets.
02/2017 - Targets can now be MetaTargets which have a list of subtargets. Subtargets
are runable, whereas metatargets are not.
func NewTarget ¶
func NewTarget() *Target
NewTarget creates a new, empty Target with the default type of "asst"
func TargetFromFile ¶
TargetFromFile creates a Target object from a yaml file
func TargetFromString ¶
TargetFromString creates a Target object from a yaml string
type TargetCommand ¶
type TargetCommand struct { Id string `yaml:"id" bson:"cmd_id"` // ID, must match ID in test file Index int `yaml:"index"` // Index > 0 => match to index in test Points uint `yaml:"points"` // Points for this command Args []string `yaml:"args"` // Argument overrides }
TargetCommands (optionally) specify information about the commands contained in TargetTests. TargetCommands allow you to assign the points for an individual command or override the input arguments.
type TargetList ¶
type TargetList struct {
Targets []*TargetListItem
}
TargetList is the JSON blob sent to clients
type TargetListItem ¶
type TargetListItem struct { Name string PrintName string Description string Active string Type string Version uint Points uint FileName string FileHash string CollabMsg string }
TargetListItem is the target detail we send to remote clients about a target
type TargetStats ¶
type TargetStats struct { TargetName string `bson:"target_name"` TargetVersion uint `bson:"target_version"` TargetType string `bson:"target_type"` MaxScore uint `bson:"max_score"` TotalSubmissions uint `bson:"total_submissions"` TotalComplete uint `bson:"total_complete"` HighScore uint `bson:"high_score"` LowScore uint `bson:"low_score"` AvgScore float64 `bson:"avg_score"` BestPerf float64 `bson:"best_perf"` WorstPerf float64 `bson:"worst_perf"` AvgPerf float64 `bson:"avg_perf"` BestSubmission string `bson:"best_submission_id"` }
type TargetTest ¶
type TargetTest struct { Id string `yaml:"id" bson:"test_id"` Scoring string `yaml:"scoring"` Points uint `yaml:"points"` MemLeakPoints uint `yaml:"mem_leak_points"` Commands []*TargetCommand `yaml:"commands"` }
A TargetTest is the specification for a single Test contained in the Target. Currently, the Test can only appear in the Target once.
type TemplOutputLine ¶
type TemplOutputLine struct { Text string `yaml:"text"` Trusted string `yaml:"trusted"` External string `yaml:"external"` }
An expected line of output, which may either be expanded or not.
type Test ¶
type Test struct { // Mongo ID ID string `yaml:"-" json:"id" bson:"_id,omitempty"` // ID of the submission this test belongs to. SubmissionID string `yaml:"-" json:"-" bson:"submission_id"` // Metadata Name string `yaml:"name" json:"name"` Description string `yaml:"description" json:"description"` Tags []string `yaml:"tags" json:"tags"` Depends []string `yaml:"depends" json:"depends"` // Configuration chunks Sys161 Sys161Conf `yaml:"sys161" json:"sys161"` Stat StatConf `yaml:"stat" json:"stat"` Monitor MonitorConf `yaml:"monitor" json:"monitor"` CommandConf []CommandConf `yaml:"commandconf" json:"commandconf"` Misc MiscConf `yaml:"misc" json:"misc"` CommandOverrides []*CommandTemplate `yaml:"commandoverrides" json:"-"` // Actual test commands to run Content string `fm:"content" yaml:"-" json:"-" bson:"-"` // Big lock that protects most fields shared between Run and getStats L *sync.Mutex `json:"-" bson:"-"` ConfString string `json:"confstring"` // Only set during once WallTime TimeFixedPoint `json:"walltime"` // Protected by L SimTime TimeFixedPoint `json:"simtime"` // Protected by L Commands []*Command `json:"commands"` // Protected by L Status []Status `json:"status"` // Protected by L Result TestResult `json:"result"` // Protected by L // Dependency data DependencyID string `json:"depid"` ExpandedDeps map[string]*Test `json:"-" bson:"-"` IsDependency bool `json:"isdependency"` // Grading. These are set when the test is being run as part of a Target. PointsAvailable uint `json:"points_avail" bson:"points_avail"` PointsEarned uint `json:"points_earned" bson:"points_earned"` ScoringMethod string `json:"scoring_method" bson:"scoring_method"` TargetName string `json:"target_name" bson:"target_name"` // Memory leak detection MemLeakBytes int `json:"mem_leak_bytes" bson:"mem_leak_bytes"` // How much are they leaking? MemLeakChecked bool `json:"mem_leak_checked" bson:"mem_leak_checked"` // Did we even check? MemLeakPoints uint `json:"mem_leak_points" bson:"mem_leak_points"` // potential point hit MemLeakDeducted uint `json:"mem_leak_deducted" bson:"mem_leak_deducted"` // actual point hit // contains filtered or unexported fields }
func TestFromFile ¶
TestFromFile parses the test file and sets configuration defaults.
func TestFromString ¶
TestFromFile parses the test string and sets configuration defaults.
func (*Test) MergeAllDefaults ¶
func (*Test) OutputJSON ¶
OutputJSON serializes the test object and all related output.
func (*Test) OutputString ¶
OutputString prints test output in a human readable form.
func (*Test) PrintConf ¶
PrintConf formats the test configuration for use by sys161 via the sys161.conf file.
func (*Test) SetEnv ¶
func (t *Test) SetEnv(env *TestEnvironment)
type Test161JobResult ¶
A Test161JobResult consists of the completed test and any error that occurred while running the test.
type Test161Stats ¶
type Test161Stats struct { Status string `json:"status"` SubmissionStats ManagerStats `json:"submission_stats"` TestStats ManagerStats `json:"test_stats"` }
Combined submission and tests statistics since the service started
type TestEnvironment ¶
type TestEnvironment struct { // These do not depend on the TestGroup/Target TestDir string Commands map[string]*CommandTemplate Targets map[string]*Target // Optional - added in version 1.2.6 Tags map[string]*TagDescription CacheDir string OverlayRoot string KeyDir string Persistence PersistenceManager Log *log.Logger RootDir string // contains filtered or unexported fields }
TestEnvironment encapsultes the environment tests runs in. Much of the environment is global - commands, targets, etc. However, some state is local, such as the secure keyMap and OS/161 root directory.
func NewEnvironment ¶
func NewEnvironment(test161Dir string, pm PersistenceManager) (*TestEnvironment, error)
Create a new TestEnvironment from the given test161 directory. The directory must contain these subdirectories: commands/ targets/ tests/ In addition to loading tests, commands, and targets, a logger is set up that writes to os.Stderr. This can be changed by changing env.Log.
func (*TestEnvironment) CopyEnvironment ¶
func (env *TestEnvironment) CopyEnvironment() *TestEnvironment
Create a new TestEnvironment by copying the global state from an existing environment. Local test state will be initialized to default values.
func (*TestEnvironment) SetNullLogger ¶
func (env *TestEnvironment) SetNullLogger()
func (*TestEnvironment) TargetList ¶
func (env *TestEnvironment) TargetList() *TargetList
type TestGroup ¶
type TestGroup struct { Tests map[string]*Test Config *GroupConfig }
A group of tests to be run, which is the result of expanding a GroupConfig.
func EmptyGroup ¶
func EmptyGroup() *TestGroup
EmptyGroup creates an empty TestGroup that can be used to add groups from strings.
func GroupFromConfig ¶
func GroupFromConfig(config *GroupConfig) (*TestGroup, []error)
Create a TestGroup from a GroupConfig. All test expressions are expanded and dependencies are added if UseDeps is set to true in the configuration.
func (*TestGroup) EarnedPoints ¶
func (*TestGroup) OutputJSON ¶
func (*TestGroup) OutputString ¶
func (*TestGroup) TotalPoints ¶
type TestResult ¶
type TestResult string
const ( TEST_RESULT_NONE TestResult = "none" // Hasn't run (initial status) TEST_RESULT_RUNNING TestResult = "running" // Running TEST_RESULT_CORRECT TestResult = "correct" // Met the output criteria TEST_RESULT_INCORRECT TestResult = "incorrect" // Possibly some partial points, but didn't complete everything successfully TEST_RESULT_ABORT TestResult = "abort" // Aborted - internal error TEST_RESULT_SKIP TestResult = "skip" // Skipped (dependency not met) )
type TestRunner ¶
type TestRunner interface { Group() *TestGroup Run() <-chan *Test161JobResult }
A TestRunner is responsible for running a TestGroup and sending the results back on a read-only channel. test161 runners close the results channel when finished so clients can range over it. test161 runners also return as soon as they are able to and let tests run asynchronously.
func NewDependencyRunner ¶
func NewDependencyRunner(group *TestGroup) TestRunner
Factory function to create a new DependencyRunner.
func NewSimpleRunner ¶
func NewSimpleRunner(group *TestGroup) TestRunner
Factory function to create a new SimpleRunner.
func TestRunnerFromConfig ¶
func TestRunnerFromConfig(config *GroupConfig) (TestRunner, []error)
Create a TestRunner from a GroupConfig. config.UseDeps determines the type of runner created.
type TestStat ¶
type TestStat struct { Name string `json:"name" bson:"name"` Result TestResult `json:"result" bson:"result"` PointsAvailable uint `json:"points_avail" bson:"points_avail"` PointsEarned uint `json:"points_earned" bson:"points_earned"` MemLeakBytes int `json:"mem_leak_bytes" bson:"mem_leak_bytes"` MemLeakPoints uint `json:"mem_leak_points" bson:"mem_leak_points"` MemLeakDeducted uint `json:"mem_leak_deducted" bson:"mem_leak_deducted"` }
type TestUpdateMsg ¶
type TestingPersistence ¶
type TestingPersistence struct {
Verbose bool
}
func (*TestingPersistence) CanRetrieve ¶
func (d *TestingPersistence) CanRetrieve() bool
func (*TestingPersistence) Close ¶
func (p *TestingPersistence) Close()
func (*TestingPersistence) Notify ¶
func (p *TestingPersistence) Notify(entity interface{}, msg, what int) error
type TimeFixedPoint ¶
type TimeFixedPoint float64
func (TimeFixedPoint) MarshalJSON ¶
func (t TimeFixedPoint) MarshalJSON() ([]byte, error)
MarshalJSON prints our TimeFixedPoint type as a fixed point float for JSON.
type UploadRequest ¶
type UploadRequest struct { UploadType int Users []*SubmissionUserInfo }
UploadRequests are created by clients and provide the form fields for file uploads. Currently, we only support stats file uploads, but this could change.
func (*UploadRequest) Validate ¶
func (req *UploadRequest) Validate(env *TestEnvironment) ([]*Student, error)
type UsageStat ¶
type UsageStat struct { ID string `bson:"_id"` Users []string `bson:"users" json:"users"` Timestamp time.Time `bson:"timestamp" json:"timestamp"` Version int `bson:"version" json:"version"` Test161Version string `bson:"test161_version" json:"test161_version"` IsStaff bool `bson:"is_staff" json:"-"` GroupInfo *GroupStat `bson:"group_info" json:"group_info"` }
func NewTestGroupUsageStat ¶
func (*UsageStat) Persist ¶
func (stat *UsageStat) Persist(env *TestEnvironment) error