簡體   English   中英

將 echo 服務器作為守護進程運行以在 python 中進行測試

[英]Running an echo server as a daemon process for testing in python

我想自動測試儀器並編寫了一個小服務器程序來模擬儀器,除非它收到特殊命令“*IDN?”,否則它將發送回命令。 當我直接在自己的腳本中運行回顯服務器,然后單獨運行客戶端腳本時,一切正常,並且我得到了預期的結果。 現在我想直接從測試腳本運行服務器。 所以我想我會使用多處理來啟動它。 但問題似乎是當服務器套接字到達 s.accept() 行時,它只是在那里等待並且永遠不會返回。 那么,如果我不能在與測試功能相同的代碼中運行此服務器,我該如何完成自動化測試呢?

import socket
import multiprocessing as mp
import time,sys

HOST = '127.0.0.1'  # Standard loopback interface address (localhost),
PORT = 65432        # Port to listen on (non-privileged ports are > 1023),
FTP_PORT = 63217    # Port for ftp testing, change to 21 for device

def handle_connection(conn,addr):
    with conn:
        conn.send('Connected by', addr)
        print("Got connection")
        data = conn.recv(1024)
        if not data:
            return 'Nodata'
        elif (data == b'*IDN?\n'):
            print('SONY/TEK,AWG520,0,SCPI:95.0 OS:3.0 USR:4.0\n')
            conn.sendall(b'SONY/TEK,AWG520,0,SCPI:95.0 OS:3.0 USR:4.0\n')
            return 'IDN'
        else:
            conn.sendall(data)
            return 'Data'


def echo_server(c_conn,host=HOST,port=PORT):
    # this server simulates the AWG command protocol, simply echoing the command back except for IDN?
    p = mp.current_process()
    print('Starting echo server:', p.name, p.pid)
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((host, port))
        s.listen()
        try:
            while True:
                print("Waiting for connection...")
                c_conn.send('waiting for connection...')
                conn, addr = s.accept()
                handle_connection(conn,addr)
                c_conn.send('serving client...')
        finally:
            conn.close()
            c_conn.send('done')
            time.sleep(2)
            print('Exiting echo server:', p.name, p.pid)
            sys.stdout.flush()



def test_echo_server():
    print("entering client part")
    with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as mysock:
        mysock.connect((HOST,PORT))
        mysock.sendall('test\n'.encode())
        data = mysock.recv(1024)
    print('received:',repr(data))


if __name__ == '__main__':
    parent_conn, child_conn = mp.Pipe()
    echo_demon = mp.Process(name='echo', target=echo_server(child_conn, ))
    echo_demon.daemon = True
    echo_demon.start()
    time.sleep(1)
    echo_demon.join(1)
    test_echo_server()
    if parent_conn.poll(1):
        print(parent_conn.recv())
    else:
        print('Waiting for echo server')


我設法使用我在 Romano、Baka 和 Phillips 的“Python 入門”一書中找到的一些代碼片段解決了我自己的問題。 這是服務器的代碼:

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind((HOST, PORT))
    s.listen()
    try:
        while True:
            print("Waiting for connection...")
            client, addr = s.accept()

            with client:            
                data = client.recv(1024)
                if not data:
                    break
                elif (data == b'*IDN?\n'):
                    client.sendall(b'SONY/TEK,AWG520,0,SCPI:95.0 OS:3.0 USR:4.0\n')
                else:
                    client.sendall(data)
    finally:     
        time.sleep(1)
        print('Exiting echo server:')

這是在單獨的進程中運行此服務器的測試文件的代碼,以及一些簡單的測試:

@pytest.fixture(scope="session")
def awgserver():
    print("loading server")
    p = subprocess.Popen(["python3", "server.py"])
    time.sleep(1)
    yield p
    p.terminate()


@pytest.fixture
def clientsocket(request):
    print("entering client part")
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as mysock:
        mysock.connect((HOST, PORT))
        yield mysock    
        mysock.close()

@pytest.mark.run_this
def test_echo(awgserver, clientsocket):
    clientsocket.send(b"*IDN?\n")
    #assert clientsocket.recv(1024) == b"SONY/TEK,AWG520,0,SCPI:95.0 OS:3.0 USR:4.0\n"
    assert clientsocket.recv(10) == b"TEK" # deliberately make test fail

@pytest.mark.run_this
def test_echo2(awgserver, clientsocket):
    clientsocket.send(b"def")
    assert clientsocket.recv(3) == b"def"

將 HOST 設置為環回 IP,將 PORT 設置為 > 1024

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM