All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.evosuite.runtime.mock.java.net.MockServerSocket Maven / Gradle / Ivy

There is a newer version: 1.0.6
Show newest version
/**
 * Copyright (C) 2010-2017 Gordon Fraser, Andrea Arcuri and EvoSuite
 * contributors
 *
 * This file is part of EvoSuite.
 *
 * EvoSuite is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3.0 of the License, or
 * (at your option) any later version.
 *
 * EvoSuite is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with EvoSuite. If not, see .
 */
package org.evosuite.runtime.mock.java.net;

import org.evosuite.runtime.mock.MockFramework;
import org.evosuite.runtime.mock.OverrideMock;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketImplFactory;
import java.net.SocketOptions;
import java.nio.channels.ServerSocketChannel;

/**
 *
 * Created by arcuri on 6/29/14.
 */
public class MockServerSocket extends ServerSocket implements OverrideMock {

	private boolean created = false;
	private boolean bound = false;
	private boolean closed = false;
	private Object closeLock = new Object();
	private boolean oldImpl = false;

	private MockSocketImpl impl;


	//--------- constructors -------------

	/**
	 *  Non-visible (package-level) constructor
	 *
	MockServerSocket(MockSocketImpl impl) {
		this.impl = impl;
		impl.setServerSocket(this);
	}
	 */

	public MockServerSocket() throws IOException {
		super();
		/*
		 * the super constructor is only calling setImpl, which is implemented with:
		 
		  	if (factory != null) {
            		impl = factory.createSocketImpl();
            		checkOldImpl();
        		} else {
            		// No need to do a checkOldImpl() here, we know it's an up to date
            		// SocketImpl!
            		impl = new SocksSocketImpl();
        		}
        		if (impl != null)
            		impl.setServerSocket(this);
            		
         * ie, the only side effect is to set the variable "impl"            		
		 */
		setImpl();
	}

	public MockServerSocket(int port) throws IOException {
		this(port, 50, null);
	}


	public MockServerSocket(int port, int backlog) throws IOException {
		this(port, backlog, null);
	}

	public MockServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {
		this();

        if (port < 0 || port > 0xFFFF)
			throw new IllegalArgumentException("Port value out of range: " + port);

        if (backlog < 1)
			backlog = 50;

        try {
            if(MockFramework.isEnabled()) {
                bind(new MockInetSocketAddress(bindAddr, port), backlog);
            } else {
                Method setImplMethod = ServerSocket.class.getDeclaredMethod("setImpl");
                setImplMethod.setAccessible(true);
                setImplMethod.invoke(this);
                super.bind(new InetSocketAddress(bindAddr, port), backlog);
            }
		} catch(SecurityException e) {
            close();
            throw e;
        } catch(IOException e) {
			close();
			throw e;
		} catch (NoSuchMethodException | IllegalAccessException e ) {
            //should never happen
            throw new RuntimeException("ERROR in EvoSuite: "+e,e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e.getCause());
        }
    }

	//-------------------------------------------------

	public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException {
		//for explanation, see MockSocket
		throw new IOException("Setting of factory is not supported in virtual network");
	}

	private void setImpl() {		
		impl = new EvoSuiteSocket();		
		impl.setServerSocket(this);
	}
	
	private MockSocketImpl getImpl() throws SocketException {
		if (!created)
			createImpl();
		return impl;
	}

    protected void setBound() {
        bound = true;
    }

    protected void setCreated() {
        created = true;
    }

	
	private void createImpl() throws SocketException {
		if (impl == null)
			setImpl();
		try {
			impl.create(true);
			created = true;
		} catch (IOException e) {
			throw new SocketException(e.getMessage());
		}
	}

    @Override
	public void bind(SocketAddress endpoint) throws IOException {
		if(!MockFramework.isEnabled()){
            super.bind(endpoint);
            return;
        }
        bind(endpoint, 50);
	}

    @Override
	public void bind(SocketAddress endpoint, int backlog) throws IOException {
        if(!MockFramework.isEnabled()){
            super.bind(endpoint,backlog);
            return;
        }

        if (isClosed())
			throw new SocketException("Socket is closed");
		if (!oldImpl && isBound())
			throw new SocketException("Already bound");
		if (endpoint == null)
			endpoint = new MockInetSocketAddress(0);
		if (!(endpoint instanceof InetSocketAddress))
			throw new IllegalArgumentException("Unsupported address type");
		
		InetSocketAddress epoint = (InetSocketAddress) endpoint;
		if (epoint.isUnresolved())
			throw new SocketException("Unresolved address");
		if (backlog < 1)
			backlog = 50;
		
		try {			
			getImpl().bind(epoint.getAddress(), epoint.getPort());
			getImpl().listen(backlog);
			bound = true;
		}  catch(IOException e) {
			bound = false;
			throw e;
		}
	}

	@Override
	public InetAddress getInetAddress() {
        if(!MockFramework.isEnabled()){
            return super.getInetAddress();
        }
        if (!isBound())
			return null;
		try {
			InetAddress in = getImpl().getInetAddress();			
			return in;
		}  catch (SocketException e) {
			// nothing
			// If we're bound, the impl has been created
			// so we shouldn't get here
		}
		return null;
	}

	@Override
	public int getLocalPort() {
        if(!MockFramework.isEnabled()){
            return super.getLocalPort();
        }
        if (!isBound())
			return -1;
		try {
			return getImpl().getLocalPort();
		} catch (SocketException e) {
			// nothing
			// If we're bound, the impl has been created
			// so we shouldn't get here
		}
		return -1;
	}

    @Override
	public SocketAddress getLocalSocketAddress() {
        if(!MockFramework.isEnabled()){
            return super.getLocalSocketAddress();
        }
        if (!isBound())
			return null;
		return new InetSocketAddress(getInetAddress(), getLocalPort());
	}

    @Override
	public Socket accept() throws IOException {
        if(!MockFramework.isEnabled()){
            return super.accept();
        }
        if (isClosed())
			throw new SocketException("Socket is closed");
		if (!isBound())
			throw new SocketException("Socket is not bound yet");
		MockSocket s = new MockSocket((MockSocketImpl) null);
		
		_implAccept(s); 
		
		return s;
	}

	protected void _implAccept(MockSocket s) throws IOException {
		MockSocketImpl si = null;
		try {
			if (s.impl == null)
				s.setImpl();
			else {
				s.impl.reset();
			}
			si = s.impl;
			s.impl = null;
			//si.address = new InetAddress(); 
			//si.fd = new FileDescriptor(); 
			
			si.setServerSocket(this);// TODO not sure if correct
			getImpl().accept(si);
			
		} catch (IOException e) {
			if (si != null)
				si.reset();
			s.impl = si;
			throw e;
		} 
		s.impl = si;
		s._postAccept();
	}

	
	/* Cannot override because final 
	protected final void implAccept(Socket s) throws IOException {
		SocketImpl si = null;
		try {
			if (s.impl == null)
				s.setImpl();
			else {
				s.impl.reset();
			}
			si = s.impl;
			s.impl = null;
			si.address = new InetAddress();
			si.fd = new FileDescriptor();
			getImpl().accept(si);

			SecurityManager security = System.getSecurityManager();
			if (security != null) {
				security.checkAccept(si.getInetAddress().getHostAddress(),
						si.getPort());
			}
		} catch (IOException e) {
			if (si != null)
				si.reset();
			s.impl = si;
			throw e;
		} catch (SecurityException e) {
			if (si != null)
				si.reset();
			s.impl = si;
			throw e;
		}
		s.impl = si;
		s.postAccept();
	}
	*/
	
	@Override
	public void close() throws IOException {
        if(!MockFramework.isEnabled()){
            super.close();
            return;
        }
        synchronized(closeLock) {
			if (isClosed())
				return;
			if (created)
				impl.close();
			closed = true;
		}
	}

	@Override
	public ServerSocketChannel getChannel() {
		return null; //TODO
	}

	@Override
	public boolean isBound() {
        if(!MockFramework.isEnabled()){
            return super.isBound();
        }
		// Before 1.3 ServerSockets were always bound during creation
		return bound || oldImpl;
	}

	@Override
	public boolean isClosed() {
        if(!MockFramework.isEnabled()){
            return super.isClosed();
        }
		synchronized(closeLock) {
			return closed;
		}
	}

	@Override
	public synchronized void setSoTimeout(int timeout) throws SocketException {
        if(!MockFramework.isEnabled()){
            super.setSoTimeout(timeout);
            return;
        }
        if (isClosed())
			throw new SocketException("Socket is closed");
		getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
	}

	@Override
	public synchronized int getSoTimeout() throws IOException {
        if(!MockFramework.isEnabled()){
            return super.getSoTimeout();
        }
        if (isClosed())
			throw new SocketException("Socket is closed");
		Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
		/* extra type safety */
		if (o instanceof Integer) {
			return ((Integer) o).intValue();
		} else {
			return 0;
		}
	}

	@Override
	public void setReuseAddress(boolean on) throws SocketException {
        if(!MockFramework.isEnabled()){
            super.setReuseAddress(on);
            return;
        }
        if (isClosed())
			throw new SocketException("Socket is closed");
		getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
	}

	@Override
	public boolean getReuseAddress() throws SocketException {
        if(!MockFramework.isEnabled()){
            return super.getReuseAddress();
        }
        if (isClosed())
			throw new SocketException("Socket is closed");
		return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
	}

	@Override
	public String toString() {
        if(!MockFramework.isEnabled()){
            return super.toString();
        }
        if (!isBound())
			return "ServerSocket[unbound]";
		
		InetAddress in = impl.getInetAddress();

		return "ServerSocket[addr=" + in + ",localport=" + impl.getLocalPort()  + "]";
	}


	@Override
	public synchronized void setReceiveBufferSize (int size) throws SocketException {
        super.setReceiveBufferSize(size);
	}

	@Override
	public synchronized int getReceiveBufferSize() throws SocketException{
		return super.getReceiveBufferSize();
	}

	@Override
	public void setPerformancePreferences(int connectionTime,
			int latency,
			int bandwidth){
		super.setPerformancePreferences(connectionTime, latency, bandwidth);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy