예제 #1
0
        /// <summary>
        /// Wraps IConnector.Connect. In addition, writes data to a sink if MillipedeConnector is
        /// initialized with Mode.Record. The returning ITransport is wrapped in a
        /// MillipedeTransport.
        /// </summary>
        /// <seealso cref="IConnector.Connect"/>
        public ITransport Connect(string address, string port, IDictionary<string, string> capabilities)
        {
            switch (recorder.Mode)
            {
            case MillipedeMode.Unconfigured:
            case MillipedeMode.PassThrough:
            default:
                return underlyingConnector.Connect(address, port, capabilities);

            case MillipedeMode.Playback:
                // Wait until a connection event comes in
                MillipedeEvent connectEvent = recorder.WaitForReplayEvent(milliDescriptor,
                    MillipedeEventType.Connected, MillipedeEventType.Exception);

                if(connectEvent.Type == MillipedeEventType.Exception)
                {
                    throw (Exception)connectEvent.Context;
                }
                if(connectEvent.Type == MillipedeEventType.Connected)
                {
                    MemoryStream stream = new MemoryStream(connectEvent.Message);
                    BinaryFormatter formatter = new BinaryFormatter();
                    object milliTransportDescriptor = formatter.Deserialize(stream);
                    string transportName = (string)formatter.Deserialize(stream);
                    Dictionary<string, string> ignored =
                        (Dictionary<string, string>)formatter.Deserialize(stream);
                    Reliability reliability = (Reliability)formatter.Deserialize(stream);
                    Ordering ordering = (Ordering)formatter.Deserialize(stream);
                    uint maxPacketSize = (uint)formatter.Deserialize(stream);

                    // FIXME: should we be checking the capabilities?  Probably...!
                    ITransport mockTransport = new MillipedeTransport(recorder,
                        milliTransportDescriptor,
                        transportName, capabilities, reliability, ordering, maxPacketSize);
                    return mockTransport;
                }
                throw new InvalidStateException("invalid event type for Connect()!", connectEvent);

            case MillipedeMode.Record:
                ITransport transport;
                try
                {
                    transport = underlyingConnector.Connect(address, port, capabilities);
                    object milliTransportDesriptor = recorder.GenerateDescriptor(transport);
                    MemoryStream stream = new MemoryStream();
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(stream, milliTransportDesriptor);
                    formatter.Serialize(stream, transport.Name);
                    formatter.Serialize(stream, capabilities);
                    formatter.Serialize(stream, transport.Reliability);
                    formatter.Serialize(stream, transport.Ordering);
                    formatter.Serialize(stream, transport.MaximumPacketSize);

                    ITransport mockTransport = new MillipedeTransport(transport, recorder,
                        milliTransportDesriptor);
                    recorder.Record(new MillipedeEvent(milliDescriptor, MillipedeEventType.Connected,
                        stream.ToArray()));
                    return mockTransport;
                }
                catch(GTException e)
                {
                    recorder.Record(new MillipedeEvent(milliDescriptor,
                        MillipedeEventType.Exception, e));
                    throw;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Wraps IAcceptor.Update.
        /// </summary>
        /// <see cref="IAcceptor.Update"/>
        public override void Update()
        {
            switch (recorder.Mode)
            {
            case MillipedeMode.Unconfigured:
            case MillipedeMode.PassThrough:
            default:
                underlyingAcceptor.Update();
                return;

            case MillipedeMode.Record:
                try
                {
                    underlyingAcceptor.Update();
                }
                catch(GTException ex)
                {
                    recorder.Record(new MillipedeEvent(milliDescriptor,
                        MillipedeEventType.Exception, ex));
                    throw;
                }
                return;

            case MillipedeMode.Playback:
                // or if recorder.Mode == MillipedeMode.PassThrough?
                // See if there's an event and process it if so
                MillipedeEvent e = recorder.CheckReplayEvent(milliDescriptor,
                    MillipedeEventType.NewClient, MillipedeEventType.Exception);
                if(e == null)
                {
                    return;
                }
                if(e.Type == MillipedeEventType.Exception)
                {
                    throw (Exception)e.Context;
                }
                Debug.Assert(e.Type == MillipedeEventType.NewClient);

                MemoryStream stream = new MemoryStream(e.Message);
                BinaryFormatter formatter = new BinaryFormatter();
                object milliTransportDescriptor = formatter.Deserialize(stream);
                string transportName = (string)formatter.Deserialize(stream);
                Dictionary<string, string> capabilities =
                    (Dictionary<string, string>)formatter.Deserialize(stream);
                Reliability reliability = (Reliability)formatter.Deserialize(stream);
                Ordering ordering = (Ordering)formatter.Deserialize(stream);
                uint maxPacketSize = (uint)formatter.Deserialize(stream);

                ITransport mockTransport = new MillipedeTransport(recorder, milliTransportDescriptor,
                    transportName, capabilities, reliability, ordering, maxPacketSize);
                NotifyNewTransport(mockTransport, capabilities);
                return;
            }
        }