feat: Testing environment
- both server and client must specify their directories
This commit is contained in:
parent
fa544ac1fb
commit
d1d5321784
59
.tmuxinator.yml
Normal file
59
.tmuxinator.yml
Normal file
@ -0,0 +1,59 @@
|
||||
# ./.tmuxinator.yml
|
||||
|
||||
name: coen366
|
||||
root: ~/Desktop/University/Fall2023_Classes/COEN366/project
|
||||
|
||||
# Optional tmux socket
|
||||
# socket_name: foo
|
||||
|
||||
# Note that the pre and post options have been deprecated and will be replaced by
|
||||
# project hooks.
|
||||
|
||||
# Project hooks
|
||||
|
||||
# Runs on project start, always
|
||||
# on_project_start: command
|
||||
|
||||
# Run on project start, the first time
|
||||
# on_project_first_start: command
|
||||
|
||||
# Run on project start, after the first time
|
||||
# on_project_restart: command
|
||||
|
||||
# Run on project exit ( detaching from tmux session )
|
||||
# on_project_exit: command
|
||||
|
||||
# Run on project stop
|
||||
# on_project_stop: command
|
||||
|
||||
# Runs in each window and pane before window/pane specific commands. Useful for setting up interpreter versions.
|
||||
# pre_window: rbenv shell 2.0.0-p247
|
||||
|
||||
# Pass command line options to tmux. Useful for specifying a different tmux.conf.
|
||||
# tmux_options: -f ~/.tmux.mac.conf
|
||||
|
||||
# Change the command to call tmux. This can be used by derivatives/wrappers like byobu.
|
||||
# tmux_command: byobu
|
||||
|
||||
# Specifies (by name or index) which window will be selected on project startup. If not set, the first window is used.
|
||||
# startup_window: editor
|
||||
|
||||
# Specifies (by index) which pane of the specified window will be selected on project startup. If not set, the first pane is used.
|
||||
# startup_pane: 1
|
||||
|
||||
# Controls whether the tmux session should be attached to automatically. Defaults to true.
|
||||
# attach: false
|
||||
|
||||
windows:
|
||||
- editor:
|
||||
root: ~/Desktop/University/Fall2023_Classes/COEN366/project
|
||||
layout: main-vertical
|
||||
panes:
|
||||
- lvim
|
||||
- test:
|
||||
layout: main-vertical
|
||||
root: ~/Desktop/University/Fall2023_Classes/COEN366/project
|
||||
panes:
|
||||
- docker-compose up --build --remove-orphans
|
||||
- sleep 15 && docker exec -it project-ftp_client-1 python client.py --debug 1
|
||||
- sleep 15 && docker exec -it project-ftp_server-1 python server.py --port_number 12000 --debug 1
|
@ -5,13 +5,12 @@ FROM python:3.11
|
||||
EXPOSE 12000
|
||||
|
||||
# Create and set the working directory
|
||||
WORKDIR /app
|
||||
WORKDIR /client
|
||||
|
||||
# Copy the local app files to the container
|
||||
COPY ./src/myftp /app
|
||||
|
||||
RUN dd if=/dev/urandom of=/app/file_local.txt bs=1024 count=10
|
||||
RUN dd if=/dev/urandom of=/app/image_local.png bs=1024 count=50
|
||||
# Copy the local client to the container
|
||||
RUN mkdir /client_directory
|
||||
RUN dd if=/dev/urandom of=/client_directory/file_local.txt bs=1024 count=10
|
||||
RUN dd if=/dev/urandom of=/client_directory/image_local.png bs=1024 count=50
|
||||
|
||||
# Start your Python application
|
||||
#CMD python client.py --debug 1
|
||||
|
@ -5,15 +5,12 @@ FROM python:3.11
|
||||
EXPOSE 12000
|
||||
|
||||
# Create and set the working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the local app files to the container
|
||||
COPY ./src/myftp /app
|
||||
WORKDIR /server
|
||||
|
||||
# Create files with random content in the /server directory
|
||||
RUN mkdir /server
|
||||
RUN dd if=/dev/urandom of=/server/file1.txt bs=1024 count=10
|
||||
RUN dd if=/dev/urandom of=/server/image1.png bs=1024 count=50
|
||||
RUN mkdir /server_directory
|
||||
RUN dd if=/dev/urandom of=/server_directory/file_server.txt bs=1024 count=10
|
||||
RUN dd if=/dev/urandom of=/server_directory/image_server.png bs=1024 count=50
|
||||
|
||||
# Start your Python application
|
||||
#CMD python server.py --port_number 12000 --debug 1
|
||||
|
@ -8,13 +8,13 @@ Zero. Only python standard libs were used.
|
||||
|
||||
### Client
|
||||
|
||||
You can run `python3 src/myftp/client.py` to start the client or `python3 src/myftp/client.py --debug 1` for debugging purposes.
|
||||
You can run `python3 src/myftp/client.py --directory <insert valid directory that you have read/write permissions>` to start the client or `python3 src/myftp/client.py --debug 1 --directory <insert valid directory that you have read/write permissions>` for debugging purposes.
|
||||
|
||||
### Server
|
||||
|
||||
By default, the server IP address or hostname or server name will be `0.0.0.0` (meaning it will bind to all interfaces). The `--port_number` flag, if not specified will be by default `12000`.
|
||||
|
||||
You can run `python3 src/myftp/server.py` to start the server or `python3 src/myftp/server.py --ip_addr <insert ip addr of the server> --port_number <insert port number here> --debug 1` for debugging purposes and to specify the port number.
|
||||
You can run `python3 src/myftp/server.py --directory <insert valid directory that you have read/write permissions>` to start the server or `python3 src/myftp/server.py --ip_addr <insert ip addr of the server> --port_number <insert port number here> --debug 1 --directory <insert valid directory that you have read/write permissions>` for debugging purposes and to specify the port number.
|
||||
|
||||
## Testing with Docker
|
||||
|
||||
@ -29,7 +29,7 @@ You can run `python3 src/myftp/server.py` to start the server or `python3 src/my
|
||||
- Wait 10 seconds.
|
||||
- 2 containers will be created on the same network `mynetwork`. Their respective IP addresses will be printed to stdout.
|
||||
- Open two terminal windows: one for each of server and client.
|
||||
- Run the server with `docker exec -it project-ftp_server_1 python server.py <insert any flags here>`.
|
||||
- Run the client with `docker exec -it project-ftp_client_1 python client.py <insert any flags here>`.
|
||||
- Run the server with `docker exec -it project-ftp_server_1 python server.py --directory /server_directory <insert any other flags here>`.
|
||||
- Run the client with `docker exec -it project-ftp_client_1 python client.py --directory /client_directory <insert any flags here>`.
|
||||
- For the client, when asked to put in the ip address and port number of the server, you can put in `ftp_server 12000` or adjust to your chosen port number. The IP address is resolved by Docker so ftp_server can not be changed.
|
||||
- Tear down everything with `docker-compose down`.
|
||||
|
@ -5,6 +5,8 @@ services:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.server
|
||||
volumes:
|
||||
- ./src/myftp:/server:ro
|
||||
networks:
|
||||
- mynetwork
|
||||
command:
|
||||
@ -22,6 +24,8 @@ services:
|
||||
dockerfile: Dockerfile.client
|
||||
networks:
|
||||
- mynetwork
|
||||
volumes:
|
||||
- ./src/myftp:/client:ro
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
|
@ -1,6 +1,7 @@
|
||||
from socket import socket, AF_INET, SOCK_DGRAM
|
||||
from typing import Tuple
|
||||
from argparse import ArgumentParser
|
||||
import os
|
||||
|
||||
# custome type to represent the hostname(server name) and the server port
|
||||
Address = Tuple[str, int]
|
||||
@ -19,12 +20,13 @@ class UDPClient:
|
||||
if not self.pong_received:
|
||||
return
|
||||
|
||||
client_socket = socket(AF_INET, SOCK_DGRAM)
|
||||
|
||||
client_socket.connect((self.server_name, self.server_port))
|
||||
client_socket = None # shutup the variableNotBound warning
|
||||
|
||||
while True:
|
||||
try:
|
||||
client_socket = socket(AF_INET, SOCK_DGRAM)
|
||||
client_socket.connect((self.server_name, self.server_port))
|
||||
|
||||
# get command from user
|
||||
while (command := input(f"myftp> - {self.mode} - : ")) not in [
|
||||
"put",
|
||||
@ -117,6 +119,20 @@ def get_address_input() -> Address:
|
||||
)
|
||||
|
||||
|
||||
def check_directory(path):
|
||||
if os.path.exists(path):
|
||||
if os.path.isdir(path):
|
||||
if os.access(path, os.R_OK) and os.access(path, os.W_OK):
|
||||
return True
|
||||
else:
|
||||
print(f"Error: The directory '{path}' is not readable or writable.")
|
||||
else:
|
||||
print(f"Error: '{path}' is not a directory.")
|
||||
else:
|
||||
print(f"Error: The directory '{path}' does not exist.")
|
||||
return False
|
||||
|
||||
|
||||
def init():
|
||||
arg_parser = ArgumentParser(description="A FTP client written in Python")
|
||||
|
||||
@ -129,6 +145,10 @@ def init():
|
||||
help="Enable or disable the flag (0 or 1)",
|
||||
)
|
||||
|
||||
arg_parser.add_argument(
|
||||
"--directory", required=True, type=str, help="Path to the client directory"
|
||||
)
|
||||
|
||||
args = arg_parser.parse_args()
|
||||
|
||||
while (
|
||||
@ -136,6 +156,12 @@ def init():
|
||||
) not in {"1", "2"}:
|
||||
print("myftp>Invalid choice. Press 1 for TCP, Press 2 for UDP")
|
||||
|
||||
if not check_directory(args.directory):
|
||||
print(
|
||||
f"The directory '{args.directory}' does not exists or is not readable/writable."
|
||||
)
|
||||
return
|
||||
|
||||
# UDP client selected here
|
||||
if protocol_selection == "2":
|
||||
user_supplied_address = get_address_input()
|
||||
|
@ -1,5 +1,6 @@
|
||||
from socket import socket, AF_INET, SOCK_DGRAM
|
||||
from argparse import ArgumentParser
|
||||
import os
|
||||
|
||||
|
||||
class UDPServer:
|
||||
@ -48,6 +49,20 @@ class UDPServer:
|
||||
print(f"myftp> - {self.mode} - Closed the server socket\n")
|
||||
|
||||
|
||||
def check_directory(path):
|
||||
if os.path.exists(path):
|
||||
if os.path.isdir(path):
|
||||
if os.access(path, os.R_OK) and os.access(path, os.W_OK):
|
||||
return True
|
||||
else:
|
||||
print(f"Error: The directory '{path}' is not readable or writable.")
|
||||
else:
|
||||
print(f"Error: '{path}' is not a directory.")
|
||||
else:
|
||||
print(f"Error: The directory '{path}' does not exist.")
|
||||
return False
|
||||
|
||||
|
||||
def init():
|
||||
parser = ArgumentParser(description="A FTP server written in Python")
|
||||
|
||||
@ -59,6 +74,10 @@ def init():
|
||||
help="Port number for the server. Default = 12000",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--directory", required=True, type=str, help="Path to the server directory"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--ip_addr",
|
||||
default="0.0.0.0",
|
||||
@ -82,6 +101,12 @@ def init():
|
||||
) not in {"1", "2"}:
|
||||
print("myftp>Invalid choice. Press 1 for TCP, Press 2 for UDP")
|
||||
|
||||
if not check_directory(args.directory):
|
||||
print(
|
||||
f"The directory '{args.directory}' does not exists or is not readable/writable."
|
||||
)
|
||||
return
|
||||
|
||||
# UDP client selected here
|
||||
if protocol_selection == "2":
|
||||
udp_server = UDPServer(args.ip_addr, args.port_number, args.debug)
|
||||
|
Loading…
x
Reference in New Issue
Block a user