Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 48 additions & 30 deletions examples/16_docker_network_python/config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@
// your assignment should fail to build.
"autograding_method" : "docker",
"container_options" : {
//States that a given testcase uses a router by default. (Default value is true)
"use_router" : true
//States that a given testcase uses a router by default. (Default value is true)
"use_router" : true
},

"autograding" : {
"work_to_details" : [ "**/*.csv", "**/*.txt" ]
"work_to_details" : [ "**/*.txt" ]
},
// Each testcase creates a new, unique set of docker containers and networks.
"testcases" : [

// *************** TEST CASES *****************
{
//Despite the default being true, this testcase will not use a router.
"use_router" : false,
Expand All @@ -28,7 +26,7 @@
//outgoing_connections list the containers that this container is allowed to network to.
"outgoing_connections" : ["client"]
// You can specify a docker image here, and if it is built on submitty, this container
// will use it. At the moment, this field defaults to ubuntu:custom if unset -- the default
// will use it. If unset, this field defaults to ubuntu:custom -- the default
// submitty image.
//container_image : <image_name>
},
Expand All @@ -38,19 +36,12 @@
// In this example, we want the server to start before the client, so we add a sleep command.
"commands" : ["sleep 2", "python3 client.py client 0"],
"outgoing_connections" : ["server"]
},
{
// At the moment, a router should always be specified, which relays student messages.
// The router should have the unique name "router."
"container_name" : "router",
"commands" : ["python3 router.py"]
}
],
"points" : 5,
"validation": [
{
"method" : "diff",
//output files are stored in a directory that matches the container_name specified above.
"actual_file" : "server/STDOUT.txt",
"expected_file" : "expected_server_output_0.txt",
"failure_message" : "ERROR: Your code did not match the expected output.",
Expand All @@ -70,19 +61,16 @@
{
"title" : "Ping Pong, Ping Pong",
"containers" : [
//This testcase is using a router, which will be injected into the network.
{
"container_name" : "server",
"commands" : ["python3 server.py server"], //string or array of strings.
"commands" : ["python3 server.py server"],
"outgoing_connections" : ["client"]
},
{
"container_name" : "client",
"commands" : ["sleep 2", "python3 client.py client 1"],
"outgoing_connections" : ["server"]
},
{
"container_name" : "router",
"commands" : ["python3 router.py"]
}
],
"points" : 5,
Expand All @@ -102,6 +90,15 @@
"failure_message" : "ERROR: Your code did not match the expected output.",
"show_message" : "on_failure",
"deduction" : 0.5
},
//Adding this "sequence_diagram" filecheck will display a sequence diagram
// of messages passed to the student.
{
"sequence_diagram" : true,
"type" : "FileCheck",
"title" : "Sequence Diagram Text File",
"actual_file" : "router/sequence_diagram.txt",
"points" : 0
}
]
},
Expand All @@ -110,17 +107,13 @@
"containers" : [
{
"container_name" : "server",
"commands" : ["python3 server.py server"], //string or array of strings.
"commands" : ["python3 server.py server"],
"outgoing_connections" : ["client"]
},
{
"container_name" : "client",
"commands" : ["sleep 2", "python3 client.py client 2"],
"outgoing_connections" : ["server"]
},
{
"container_name" : "router",
"commands" : ["python3 router.py"]
}
],
"points" : 5,
Expand All @@ -140,6 +133,15 @@
"failure_message" : "ERROR: Your code did not match the expected output.",
"show_message" : "on_failure",
"deduction" : 0.5
},
//Adding this "sequence_diagram" filecheck will display a sequence diagram
// of messages passed to the student.
{
"sequence_diagram" : true,
"type" : "FileCheck",
"title" : "Sequence Diagram Text File",
"actual_file" : "router/sequence_diagram.txt",
"points" : 0
}
]
},
Expand All @@ -148,17 +150,13 @@
"containers" : [
{
"container_name" : "server",
"commands" : ["python3 server.py server"], //string or array of strings.
"commands" : ["python3 server.py server"],
"outgoing_connections" : ["client"]
},
{
"container_name" : "client",
"commands" : ["sleep 2", "python3 client.py client 3"],
"outgoing_connections" : ["server"]
},
{
"container_name" : "router",
"commands" : ["python3 router.py"]
}
],
"points" : 5,
Expand All @@ -178,6 +176,15 @@
"failure_message" : "ERROR: Your code did not match the expected output.",
"show_message" : "on_failure",
"deduction" : 0.5
},
//Adding this "sequence_diagram" filecheck will display a sequence diagram
// of messages passed to the student.
{
"sequence_diagram" : true,
"type" : "FileCheck",
"title" : "Sequence Diagram Text File",
"actual_file" : "router/sequence_diagram.txt",
"points" : 0
}
]
},
Expand All @@ -187,17 +194,19 @@
"containers" : [
{
"container_name" : "server",
"commands" : ["python3 server.py server udp_enabled"], //string or array of strings.
"commands" : ["python3 server.py server udp_enabled"],
"outgoing_connections" : ["client"]
},
{
"container_name" : "client",
"commands" : ["sleep 2", "python3 client.py client 4 udp_enabled"],
"outgoing_connections" : ["server"]
},
//This testcase uses a custom router. This container must be named router
// and will automatically be connected up correctly.
{
"container_name" : "router",
"commands" : ["python3 router.py"]
"commands" : ["python3 custom_router.py"]
}
],
"points" : 5,
Expand All @@ -209,6 +218,15 @@
"failure_message" : "ERROR: Your code did not match the expected output.",
"show_message" : "on_failure",
"deduction" : 1.0
},
//Adding this "sequence_diagram" filecheck will display a sequence diagram
// of messages passed to the student.
{
"sequence_diagram" : true,
"type" : "FileCheck",
"title" : "Sequence Diagram Text File",
"actual_file" : "router/sequence_diagram.txt",
"points" : 0
}
]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import socket
import sys
import csv
import traceback
import queue
import errno
from time import sleep
import os
import datetime
import random
from datetime import timedelta

from submitty_router import submitty_router

#Custom router extends submitty_router
class custom_router(submitty_router):
# The constructor for our custom router
def __init__(self, seed=None, log_file='router_log.txt'):
super().__init__(seed=seed, log_file=log_file)

'''
Override this function to manipuate student messages.
'''
def manipulate_recieved_message(self, sender, recipient, port, message, message_number):
now = datetime.datetime.now()
# The total time the program has been running as of right now.
elapsed_time = now - self.execution_start_time
# Use the time at which this message will be processed. Set to now initially.
process_time = now
# Leave blank to avoid outputting a message to the student on their sequence diagram
message_to_student = None
#If true, this message is entirely discarded.
drop_me = False

#EXAMPLE: modify one bit of the student's message in 1/10 messages before 2 seconds
if random.randint(1,10) == 10 and elapsed_time.total_seconds() <= 2:
# Convert the message int an array of bytes
m_array = bytearray(message)
# Determine which bit will be flipped
flipbit = random.randint(0,len(m_array)-1 )
# Flip the bit
m_array[flipbit] = m_array[flipbit] + 1
# Update the message
message = bytes(m_array)
# OPTIONAL: Tell the student that their message was corrupted via a message in their sequence diagram.
message_to_student = "Corrupted"
#EXAMPLE: delay the student message by up to 1 second in 1/10 messages
elif random.randint(1,10) == 10:
# Choose an amount of delay (in ms) between .1 and 1 second.
milliseconds_dela = random.randint(100,1000)
# Extend the processing time that far into the future
process_time = process_time + timedelta(milliseconds=milliseconds_dela)
# OPTIONAL: add a message to the student's sequence diagram that lets them know about the delay
message_to_student = "Delayed {0} ms".format(milliseconds_dela)
#We drop 1/10th of packets
elif random.randint(1,10) == 10:
drop_me = True

data = {
'sender' : sender,
'recipient' : recipient,
'port' : port,
'message' : message,
'message_to_student' : message_to_student,
'drop_message' : drop_me
}
return (process_time, data)


#You must provide a main which is capable of running your router.
if __name__ == '__main__':
router = custom_router()
router.log("This is the custom router!")
# submitty_router provides init and run functions for you to call.
router.init()
router.run()