コード例 #1
0
    /// <summary>
    /// Implementation of the test itself.
    /// </summary>
    /// <returns>true if the test passes, false otherwise.</returns>
    public override async Task<bool> RunAsync()
    {
      IPAddress ServerIp = (IPAddress)ArgumentValues["Server IP"];
      int PrimaryPort = (int)ArgumentValues["primary Port"];
      int BasePort = (int)ArgumentValues["Base Port"];
      log.Trace("(ServerIp:'{0}',PrimaryPort:{1},BasePort:{2})", ServerIp, PrimaryPort, BasePort);

      bool res = false;
      Passed = false;

      ProtocolClient client = new ProtocolClient();
      ProfileServer profileServer = null;
      try
      {
        MessageBuilder mb = client.MessageBuilder;

        // Step 1
        log.Trace("Step 1");
        // Get port list.
        await client.ConnectAsync(ServerIp, PrimaryPort, false);
        Dictionary<ServerRoleType, uint> rolePorts = new Dictionary<ServerRoleType, uint>();
        bool listPortsOk = await client.ListServerPorts(rolePorts);
        client.CloseConnection();


        bool profileInitializationOk = true;
        byte[] testImageData = File.ReadAllBytes(Path.Combine("images", TestName + ".jpg"));

        int profileIndex = 1;
        int profileCount = 10;
        for (int i = 0; i < profileCount; i++)
        {
          ProtocolClient profileClient = new ProtocolClient();
          profileClient.InitializeRandomProfile(profileIndex, testImageData);
          profileIndex++;

          if (!await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
          {
            profileClient.Dispose();
            profileInitializationOk = false;
            break;
          }

          TestProfiles.Add(profileClient.Profile.Name, profileClient);
        }

        profileServer = new ProfileServer("TestServer", ServerIp, BasePort, client.GetIdentityKeys());
        bool serverStartOk = profileServer.Start();

        bool step1Ok = listPortsOk && profileInitializationOk && serverStartOk;
        log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");



        // Step 2
        log.Trace("Step 2");
        await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);
        bool neighborhoodInitializationProcessOk = await client.NeighborhoodInitializationProcessAsync(profileServer.PrimaryPort, 1, TestProfiles);

        bool step2Ok = neighborhoodInitializationProcessOk;

        log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");


        // Step 3
        log.Trace("Step 3");

        profileInitializationOk = true;
        profileCount = 5;
        Dictionary<string, ProtocolClient> newProfiles = new Dictionary<string, ProtocolClient>(StringComparer.Ordinal);
        for (int i = 0; i < profileCount; i++)
        {
          ProtocolClient profileClient = new ProtocolClient();
          profileClient.InitializeRandomProfile(profileIndex, testImageData);
          profileIndex++;

          if (!await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
          {
            profileClient.Dispose();
            profileInitializationOk = false;
            break;
          }

          TestProfiles.Add(profileClient.Profile.Name, profileClient);
          newProfiles.Add(profileClient.Profile.Name, profileClient);
        }

        // Wait at most 12 minutes for updates from the server.
        List<SharedProfileAddItem> addUpdates = new List<SharedProfileAddItem>();
        bool profilesOk = false;
        for (int time = 0; time < 12 * 60; time++) 
        {
          await Task.Delay(1000);

          // Meanwhile we expect updates to arrive on our simulated profile server.
          bool error = false;
          List<IncomingServerMessage> psMessages = profileServer.GetMessageList();
          foreach (IncomingServerMessage ism in psMessages)
          {
            if (ism.Role != ServerRole.ServerNeighbor) continue;
            Message message = ism.IncomingMessage;

            if ((message.MessageTypeCase == Message.MessageTypeOneofCase.Request)
              && (message.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest)
              && (message.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate))
            {
              foreach (SharedProfileUpdateItem updateItem in message.Request.ConversationRequest.NeighborhoodSharedProfileUpdate.Items)
              {
                if (updateItem.ActionTypeCase == SharedProfileUpdateItem.ActionTypeOneofCase.Add)
                {
                  SharedProfileAddItem addItem = updateItem.Add;
                  addUpdates.Add(addItem);
                }
                else
                {
                  log.Trace("Received invalid update action type {0}.", updateItem.ActionTypeCase);
                  error = true;
                  break;
                }
              }
            }

            if (error) break;
          }
          // Terminate if any error occurred.
          if (error) break;

          // Terminate if the received profiles match what is expected.
          profilesOk = client.CheckProfileListMatchAddItems(newProfiles, addUpdates);
          if (profilesOk) break;

          // Terminate if we do not expect any more updates to come.
          if (addUpdates.Count >= newProfiles.Count) break;
        }

        bool step3Ok = profileInitializationOk && profilesOk;

        log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");


        Passed = step1Ok && step2Ok && step3Ok;

        res = true;
      }
      catch (Exception e)
      {
        log.Error("Exception occurred: {0}", e.ToString());
      }
      client.Dispose();

      foreach (ProtocolClient protocolClient in TestProfiles.Values)
        protocolClient.Dispose();

      if (profileServer != null) profileServer.Shutdown();

      log.Trace("(-):{0}", res);
      return res;
    }
コード例 #2
0
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];
            int       BasePort    = (int)ArgumentValues["Base Port"];
            int       LocPort     = (int)ArgumentValues["LOC Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1},BasePort:{2},LocPort:{3})", ServerIp, PrimaryPort, BasePort, LocPort);

            bool res = false;

            Passed = false;

            ProtocolClient client        = new ProtocolClient();
            ProfileServer  profileServer = null;
            LocServer      locServer     = null;

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");

                // Get port list.
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client.ListServerPorts(rolePorts);

                client.CloseConnection();


                // Radius generation.
                R2 = (uint)Rng.Next(R2Min, R2Max);
                R1 = (uint)Rng.Next(R1Min, (int)(R1R2RatioMax * R2));
                R3 = (uint)Rng.Next((int)(R3R2RatioMax * R2), R3Max);
                log.Trace("R1: {0,8} m", R1);
                log.Trace("R2: {0,8} m", R2);
                log.Trace("R3: {0,8} m", R3);

                // Location generation
                for (int i = 0; i < LocationCount; i++)
                {
                    if (PredefinedLocations.Count > i)
                    {
                        GeneratedLocations.Add(GenerateLocation(PredefinedLocations[i], R2));
                    }
                    else
                    {
                        int lat = Rng.Next((int)(GpsLocation.LatitudeMin * GpsLocation.LocationTypeFactor), (int)(GpsLocation.LatitudeMax * GpsLocation.LocationTypeFactor) + 1);
                        int lon = Rng.Next((int)(GpsLocation.LongitudeMin * GpsLocation.LocationTypeFactor) + 1, (int)(GpsLocation.LongitudeMax * GpsLocation.LocationTypeFactor) + 1);
                        GeneratedLocations.Add(new GpsLocation(lat, lon));
                    }
                }

                log.Trace("Generated locations:");
                for (int i = 0; i < LocationCount; i++)
                {
                    log.Trace(" #{0:00}: {1:US}", i, GeneratedLocations[i]);
                }


                // Create identities.
                int    profileNumber = 0;
                byte[] imageData     = File.ReadAllBytes(Path.Combine("images", TestName + ".png"));

                uint[] rads = new uint[] { R1, R2, R3 };
                for (int locIndex = 0; locIndex < LocationCount; locIndex++)
                {
                    for (uint radIndex = 0; radIndex < rads.Length; radIndex++)
                    {
                        for (int idIndex = 0; idIndex < RadiusIdentityCount; idIndex++)
                        {
                            GpsLocation basePoint = GeneratedLocations[locIndex];
                            uint        radius    = rads[radIndex];
                            GpsLocation location  = GenerateLocation(basePoint, radius);
                            ProfileLocations.Add(location);

                            ProtocolClient profileClient = new ProtocolClient();
                            profileClient.InitializeRandomProfile(profileNumber, imageData);
                            profileNumber++;
                            profileClient.Profile.Location = location;

                            TestProfiles.Add(profileClient.Profile.Name, profileClient);
                            ProfileNames.Add(profileClient.Profile.Name);
                        }
                    }
                }


                // Start simulated profile server.
                profileServer = new ProfileServer("TestProfileServer", ServerIp, BasePort, client.GetIdentityKeys(), new GpsLocation(1, 2));
                bool profileServerStartOk = profileServer.Start();

                // Start simulated LOC server.
                locServer = new LocServer("TestLocServer", ServerIp, LocPort);
                bool locServerStartOk = locServer.Start();

                await locServer.WaitForProfileServerConnectionAsync();

                bool step1Ok = profileServerStartOk && locServerStartOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");


                // Step 2
                log.Trace("Step 2");

                // Announce new neighbor.
                Iop.Locnet.NeighbourhoodChange change = new Iop.Locnet.NeighbourhoodChange()
                {
                    AddedNodeInfo = profileServer.GetNodeInfo(LocPort)
                };

                bool changeNotificationOk = await locServer.SendChangeNotification(change);

                // Wait for start of neighborhood initialization process.
                IncomingServerMessage incomingServerMessage = await profileServer.WaitForConversationRequest(ServerRole.ServerNeighbor, ConversationRequest.RequestTypeOneofCase.StartNeighborhoodInitialization);


                // Send update.
                bool statusOk = false;
                bool updateOk = true;
                List <ProtocolClient> profilesToSend = new List <ProtocolClient>(TestProfiles.Values);
                while (profilesToSend.Count > 0)
                {
                    int batchSize = Rng.Next(1, Math.Min(100, profilesToSend.Count) + 1);

                    List <SharedProfileUpdateItem> updateItems = new List <SharedProfileUpdateItem>();
                    foreach (ProtocolClient pc in profilesToSend.GetRange(0, batchSize))
                    {
                        updateItems.Add(pc.GetSharedProfileUpdateAddItem());
                    }

                    profilesToSend.RemoveRange(0, batchSize);

                    Message updateRequest = await profileServer.SendNeighborhoodSharedProfileUpdateRequest(incomingServerMessage.Client, updateItems);

                    incomingServerMessage = await profileServer.WaitForResponse(ServerRole.ServerNeighbor, updateRequest);

                    statusOk = incomingServerMessage.IncomingMessage.Response.Status == Status.Ok;
                    bool batchOk = (updateRequest != null) && statusOk;
                    if (!batchOk)
                    {
                        updateOk = false;
                        break;
                    }
                }


                // Finish neighborhood initialization process.
                Message finishRequest = await profileServer.SendFinishNeighborhoodInitializationRequest(incomingServerMessage.Client);

                incomingServerMessage = await profileServer.WaitForResponse(ServerRole.ServerNeighbor, finishRequest);

                statusOk = incomingServerMessage.IncomingMessage.Response.Status == Status.Ok;
                bool finishOk = (finishRequest != null) && statusOk;


                bool step2Ok = changeNotificationOk && updateOk && finishOk;
                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");



                // Step 3
                log.Trace("Step 3");

                // Start conversation.
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], true);

                bool startConversationOk = await client.StartConversationAsync();

                HashSet <byte[]> expectedCoveredServers = new HashSet <byte[]>(StructuralEqualityComparer <byte[]> .Default)
                {
                    client.GetIdentityId(), Crypto.Sha256(client.ServerKey)
                };

                // Search all profiles.
                Message requestMessage = mb.CreateProfileSearchRequest(null, null, null, null, 0, 1000, 1000, false, false);
                await client.SendMessageAsync(requestMessage);

                Message responseMessage = await client.ReceiveMessageAsync();

                bool idOk = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;


                bool totalRecordCountOk       = responseMessage.Response.ConversationResponse.ProfileSearch.TotalRecordCount == ProfileNames.Count;
                bool maxResponseRecordCountOk = responseMessage.Response.ConversationResponse.ProfileSearch.MaxResponseRecordCount == 1000;
                bool profilesCountOk          = responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.Count == ProfileNames.Count;

                HashSet <byte[]> realCoveredServers = new HashSet <byte[]>(StructuralEqualityComparer <byte[]> .Default);
                foreach (ByteString csId in responseMessage.Response.ConversationResponse.ProfileSearch.CoveredServers)
                {
                    realCoveredServers.Add(csId.ToByteArray());
                }
                bool coveredServersOk = expectedCoveredServers.SetEquals(realCoveredServers);


                bool queryRespOk = idOk && statusOk && totalRecordCountOk && maxResponseRecordCountOk && profilesCountOk;
                bool resultsOk   = client.CheckProfileListMatchSearchResultItems(TestProfiles, responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.ToList(), false, false, client.GetIdentityId(), false);

                bool query1Ok = queryRespOk && resultsOk;

                bool queriesOk = true;
                // Search queries around target locations.
                for (int locIndex = 0; locIndex < LocationCount; locIndex++)
                {
                    for (uint radIndex = 0; radIndex < rads.Length + 1; radIndex++)
                    {
                        uint        radius         = radIndex < rads.Length ? rads[radIndex] : (uint)Rng.Next(1000000, 10000000);
                        GpsLocation targetLocation = GeneratedLocations[locIndex];
                        requestMessage = mb.CreateProfileSearchRequest(null, null, null, targetLocation, radius, 1000, 1000, false, false);
                        await client.SendMessageAsync(requestMessage);

                        responseMessage = await client.ReceiveMessageAsync();

                        idOk     = responseMessage.Id == requestMessage.Id;
                        statusOk = responseMessage.Response.Status == Status.Ok;

                        Dictionary <string, ProtocolClient> expectedClients = GetClientsInLocation(targetLocation, radius);
                        totalRecordCountOk       = responseMessage.Response.ConversationResponse.ProfileSearch.TotalRecordCount == expectedClients.Count;
                        maxResponseRecordCountOk = responseMessage.Response.ConversationResponse.ProfileSearch.MaxResponseRecordCount == 1000;
                        profilesCountOk          = responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.Count == expectedClients.Count;

                        queryRespOk = idOk && statusOk && totalRecordCountOk && maxResponseRecordCountOk && profilesCountOk;
                        resultsOk   = client.CheckProfileListMatchSearchResultItems(expectedClients, responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.ToList(), false, false, client.GetIdentityId(), false);

                        queriesOk = queryRespOk && resultsOk;
                        if (!queriesOk)
                        {
                            log.Trace("Search query location {0} with radius {1} should produce {2} profiles, but produced {3} profiles.", targetLocation, radius, expectedClients.Count, responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.Count);
                            log.Trace("Expected names list:");
                            foreach (string name in expectedClients.Keys)
                            {
                                log.Trace("  {0}", name);
                            }

                            List <string> resultNames = responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.Select(r => r.Name).OrderBy(r => r).ToList();
                            log.Trace("Query result names list:");
                            foreach (string name in resultNames)
                            {
                                log.Trace("  {0}", name);
                            }
                            break;
                        }

                        log.Trace("Search query location {0} with radius {1} produced {2} correct profiles.", targetLocation, radius, expectedClients.Count);
                    }

                    if (!queriesOk)
                    {
                        break;
                    }
                }

                // Step 3 Acceptance
                bool step3Ok = startConversationOk && query1Ok && queriesOk;

                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");


                Passed = step1Ok && step2Ok && step3Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();

            foreach (ProtocolClient protocolClient in TestProfiles.Values)
            {
                protocolClient.Dispose();
            }

            if (profileServer != null)
            {
                profileServer.Shutdown();
            }
            if (locServer != null)
            {
                locServer.Shutdown();
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
コード例 #3
0
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1})", ServerIp, PrimaryPort);

            bool res = false;

            Passed = false;

            ProtocolClient client1 = new ProtocolClient();
            ProtocolClient client2 = new ProtocolClient();

            try
            {
                MessageBuilder mb = client1.MessageBuilder;

                // Step 1
                log.Trace("Step 1");
                // Get port list.
                await client1.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client1.ListServerPorts(rolePorts);

                client1.CloseConnection();


                bool   profileInitializationOk = true;
                byte[] testImageData           = File.ReadAllBytes(Path.Combine("images", TestName + ".jpg"));

                int profileIndex = 1;
                int profileCount = 10;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        TestProfiles.Add(profileClient.Profile.Name, profileClient);
                    }
                    else
                    {
                        profileClient.Dispose();
                        profileInitializationOk = false;
                        break;
                    }
                }


                bool step1Ok = listPortsOk && profileInitializationOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");



                // Step 2
                log.Trace("Step 2");
                await client1.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool neighborhoodInitializationProcessOk = await client1.NeighborhoodInitializationProcessAsync(1, 1, TestProfiles);

                client1.CloseConnection();

                bool step2Ok = neighborhoodInitializationProcessOk;

                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");


                // Step 3
                log.Trace("Step 3");

                await client2.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool verifyIdentityOk = await client2.VerifyIdentityAsync();

                // Start neighborhood initialization process.
                Message requestMessage = client2.MessageBuilder.CreateStartNeighborhoodInitializationRequest(2, 2);
                await client2.SendMessageAsync(requestMessage);

                Message responseMessage = await client2.ReceiveMessageAsync();

                bool idOk     = responseMessage.Id == requestMessage.Id;
                bool statusOk = responseMessage.Response.Status == Status.ErrorRejected;
                bool startNeighborhoodInitializationOk = idOk && statusOk;

                bool step3Ok = profileInitializationOk && startNeighborhoodInitializationOk;

                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");



                Passed = step1Ok && step2Ok && step3Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client1.Dispose();
            client2.Dispose();

            foreach (ProtocolClient protocolClient in TestProfiles.Values)
            {
                protocolClient.Dispose();
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
コード例 #4
0
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1})", ServerIp, PrimaryPort);

            bool res = false;

            Passed = false;

            ProtocolClient client1 = new ProtocolClient();
            ProtocolClient client2 = new ProtocolClient();

            try
            {
                MessageBuilder mb = client1.MessageBuilder;

                // Step 1
                log.Trace("Step 1");
                // Get port list.
                await client1.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client1.ListServerPorts(rolePorts);

                client1.CloseConnection();


                bool   profileInitializationOk = true;
                byte[] testImageData           = File.ReadAllBytes(Path.Combine("images", TestName + ".jpg"));

                int profileIndex = 1;
                int profileCount = 10;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        TestProfiles.Add(profileClient.Profile.Name, profileClient);
                    }
                    else
                    {
                        profileClient.Dispose();
                        profileInitializationOk = false;
                        break;
                    }
                }


                bool step1Ok = listPortsOk && profileInitializationOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");



                // Step 2
                log.Trace("Step 2");
                await client1.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool verifyIdentityOk = await client1.VerifyIdentityAsync();

                // Start neighborhood initialization process.
                Message requestMessage = mb.CreateStartNeighborhoodInitializationRequest(1, 1);
                await client1.SendMessageAsync(requestMessage);

                Message responseMessage = await client1.ReceiveMessageAsync();

                bool idOk     = responseMessage.Id == requestMessage.Id;
                bool statusOk = responseMessage.Response.Status == Status.Ok;
                bool startNeighborhoodInitializationOk = idOk && statusOk;

                bool step2Ok = verifyIdentityOk && startNeighborhoodInitializationOk;

                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");


                // Step 3
                log.Trace("Step 3");
                await client2.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                verifyIdentityOk = await client2.VerifyIdentityAsync();

                // Start neighborhood initialization process.
                requestMessage = client2.MessageBuilder.CreateStartNeighborhoodInitializationRequest(2, 2);
                await client2.SendMessageAsync(requestMessage);

                responseMessage = await client2.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.ErrorBusy;
                startNeighborhoodInitializationOk = idOk && statusOk;

                client2.CloseConnection();

                bool step3Ok = verifyIdentityOk && startNeighborhoodInitializationOk;

                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");



                // Step 4
                log.Trace("Step 4");

                // Wait for update request.
                Message serverRequestMessage  = null;
                Message clientResponseMessage = null;
                bool    typeOk = false;

                List <SharedProfileAddItem> receivedItems = new List <SharedProfileAddItem>();

                bool error = false;
                while (receivedItems.Count < TestProfiles.Count)
                {
                    serverRequestMessage = await client1.ReceiveMessageAsync();

                    typeOk = serverRequestMessage.MessageTypeCase == Message.MessageTypeOneofCase.Request &&
                             serverRequestMessage.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest &&
                             serverRequestMessage.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate;

                    clientResponseMessage = mb.CreateNeighborhoodSharedProfileUpdateResponse(serverRequestMessage);
                    await client1.SendMessageAsync(clientResponseMessage);


                    if (!typeOk)
                    {
                        break;
                    }

                    foreach (SharedProfileUpdateItem updateItem in serverRequestMessage.Request.ConversationRequest.NeighborhoodSharedProfileUpdate.Items)
                    {
                        if (updateItem.ActionTypeCase != SharedProfileUpdateItem.ActionTypeOneofCase.Add)
                        {
                            log.Trace("Received invalid update item action type '{0}'.", updateItem.ActionTypeCase);
                            error = true;
                            break;
                        }

                        receivedItems.Add(updateItem.Add);
                    }

                    if (error)
                    {
                        break;
                    }
                }

                log.Trace("Received {0} profiles from target profile server.", receivedItems.Count);
                bool receivedProfilesOk = !error && client1.CheckProfileListMatchAddItems(TestProfiles, receivedItems);

                // Wait for finish request.
                serverRequestMessage = await client1.ReceiveMessageAsync();

                typeOk = serverRequestMessage.MessageTypeCase == Message.MessageTypeOneofCase.Request &&
                         serverRequestMessage.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest &&
                         serverRequestMessage.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.FinishNeighborhoodInitialization;

                bool finishNeighborhoodInitializationResponseOk = typeOk;

                clientResponseMessage = mb.CreateFinishNeighborhoodInitializationResponse(serverRequestMessage);
                await client1.SendMessageAsync(clientResponseMessage);

                client1.CloseConnection();

                bool step4Ok = verifyIdentityOk && startNeighborhoodInitializationOk && receivedProfilesOk && finishNeighborhoodInitializationResponseOk;

                log.Trace("Step 4: {0}", step4Ok ? "PASSED" : "FAILED");


                // Step 5
                log.Trace("Step 5");
                await client2.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool neighborhoodInitializationProcessOk = await client2.NeighborhoodInitializationProcessAsync(2, 2, TestProfiles);

                client2.CloseConnection();

                bool step5Ok = neighborhoodInitializationProcessOk;

                log.Trace("Step 5: {0}", step5Ok ? "PASSED" : "FAILED");



                Passed = step1Ok && step2Ok && step3Ok && step4Ok && step5Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client1.Dispose();
            client2.Dispose();

            foreach (ProtocolClient protocolClient in TestProfiles.Values)
            {
                protocolClient.Dispose();
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
コード例 #5
0
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];
            int       BasePort    = (int)ArgumentValues["Base Port"];
            int       LocPort     = (int)ArgumentValues["LOC Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1},BasePort:{2},LocPort:{3})", ServerIp, PrimaryPort, BasePort, LocPort);

            bool res = false;

            Passed = false;

            ProtocolClient client        = new ProtocolClient();
            ProfileServer  profileServer = null;
            LocServer      locServer     = null;

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");

                // Get port list.
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client.ListServerPorts(rolePorts);

                client.CloseConnection();

                // Create identities.
                int    profileNumber = 0;
                byte[] imageData     = File.ReadAllBytes(Path.Combine("images", TestName + ".png"));

                for (int i = 0; i < 20500; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileNumber, imageData);
                    profileNumber++;
                    TestProfiles.Add(profileClient.Profile.Name, profileClient);
                }


                // Start simulated profile server.
                profileServer = new ProfileServer("TestProfileServer", ServerIp, BasePort, client.GetIdentityKeys(), new GpsLocation(1, 2));
                bool profileServerStartOk = profileServer.Start();

                // Start simulated LOC server.
                locServer = new LocServer("TestLocServer", ServerIp, LocPort);
                bool locServerStartOk = locServer.Start();

                await locServer.WaitForProfileServerConnectionAsync();

                bool step1Ok = profileServerStartOk && locServerStartOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");


                // Step 2
                log.Trace("Step 2");

                // Announce new neighbor.
                Iop.Locnet.NeighbourhoodChange change = new Iop.Locnet.NeighbourhoodChange()
                {
                    AddedNodeInfo = profileServer.GetNodeInfo(LocPort)
                };

                bool changeNotificationOk = await locServer.SendChangeNotification(change);

                // Wait for start of neighborhood initialization process.
                IncomingServerMessage incomingServerMessage = await profileServer.WaitForConversationRequest(ServerRole.ServerNeighbor, ConversationRequest.RequestTypeOneofCase.StartNeighborhoodInitialization);


                // Send update.
                bool statusOk     = false;
                bool updateOk     = true;
                int  profilesSent = 0;
                List <ProtocolClient> profilesToSend = new List <ProtocolClient>(TestProfiles.Values);
                while (profilesToSend.Count > 0)
                {
                    int batchSize = Math.Min(Rng.Next(100, 150), profilesToSend.Count);

                    List <SharedProfileUpdateItem> updateItems = new List <SharedProfileUpdateItem>();
                    foreach (ProtocolClient pc in profilesToSend.GetRange(0, batchSize))
                    {
                        updateItems.Add(pc.GetSharedProfileUpdateAddItem());
                    }

                    profilesToSend.RemoveRange(0, batchSize);

                    Message updateRequest = await profileServer.SendNeighborhoodSharedProfileUpdateRequest(incomingServerMessage.Client, updateItems);

                    profilesSent         += batchSize;
                    incomingServerMessage = await profileServer.WaitForResponse(ServerRole.ServerNeighbor, updateRequest);

                    if (profilesSent <= 20000)
                    {
                        statusOk = incomingServerMessage.IncomingMessage.Response.Status == Status.Ok;
                        bool batchOk = (updateRequest != null) && statusOk;
                        if (!batchOk)
                        {
                            updateOk = false;
                            break;
                        }
                    }
                    else
                    {
                        statusOk = incomingServerMessage.IncomingMessage.Response.Status == Status.ErrorInvalidValue;
                        int    badIndex        = 20000 - (profilesSent - batchSize);
                        string expectedDetails = badIndex.ToString() + ".add";
                        log.Trace("Expected details are '{0}'.", expectedDetails);

                        bool detailsOk = incomingServerMessage.IncomingMessage.Response.Details == expectedDetails;
                        bool batchOk   = (updateRequest != null) && statusOk && detailsOk;

                        if (!batchOk)
                        {
                            updateOk = false;
                        }

                        break;
                    }
                }


                bool step2Ok = changeNotificationOk && updateOk;
                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");



                // Step 3
                log.Trace("Step 3");

                // Start conversation.
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], true);

                bool startConversationOk = await client.StartConversationAsync();

                HashSet <byte[]> expectedCoveredServers = new HashSet <byte[]>(StructuralEqualityComparer <byte[]> .Default)
                {
                    client.GetIdentityId(), Crypto.Sha256(client.ServerKey)
                };

                // Search all profiles.
                Message requestMessage = mb.CreateProfileSearchRequest(null, null, null, null, 0, 100, 100);
                await client.SendMessageAsync(requestMessage);

                Message responseMessage = await client.ReceiveMessageAsync();

                bool idOk = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;


                bool totalRecordCountOk       = responseMessage.Response.ConversationResponse.ProfileSearch.TotalRecordCount == 0;
                bool maxResponseRecordCountOk = responseMessage.Response.ConversationResponse.ProfileSearch.MaxResponseRecordCount == 100;
                bool profilesCountOk          = responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.Count == 0;

                bool queryOk = idOk && statusOk && totalRecordCountOk && maxResponseRecordCountOk && profilesCountOk;

                // Step 3 Acceptance
                bool step3Ok = startConversationOk && queryOk;

                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");


                Passed = step1Ok && step2Ok && step3Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();

            foreach (ProtocolClient protocolClient in TestProfiles.Values)
            {
                protocolClient.Dispose();
            }

            if (profileServer != null)
            {
                profileServer.Shutdown();
            }
            if (locServer != null)
            {
                locServer.Shutdown();
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
コード例 #6
0
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];
            int       BasePort    = (int)ArgumentValues["Base Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1},BasePort:{2})", ServerIp, PrimaryPort, BasePort);

            bool res = false;

            Passed = false;

            ProtocolClient client1       = new ProtocolClient();
            ProtocolClient client2       = new ProtocolClient(0, SemVer.V100, client1.GetIdentityKeys());
            ProfileServer  profileServer = null;

            try
            {
                MessageBuilder mb1 = client1.MessageBuilder;
                MessageBuilder mb2 = client2.MessageBuilder;

                // Step 1
                log.Trace("Step 1");
                // Get port list.
                await client1.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client1.ListServerPorts(rolePorts);

                client1.CloseConnection();


                bool   profileInitializationOk = true;
                byte[] testImageData           = File.ReadAllBytes(Path.Combine("images", TestName + ".jpg"));

                int profileIndex = 1;
                int profileCount = 10;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (!await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        profileClient.Dispose();
                        profileInitializationOk = false;
                        break;
                    }

                    TestProfiles.Add(profileClient.Profile.Name, profileClient);
                }

                profileServer = new ProfileServer("TestServer", ServerIp, BasePort, client1.GetIdentityKeys());
                bool serverStartOk = profileServer.Start();

                bool step1Ok = listPortsOk && profileInitializationOk && serverStartOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");



                // Step 2
                log.Trace("Step 2");
                await client1.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool verifyIdentityOk = await client1.VerifyIdentityAsync();

                // Start neighborhood initialization process.
                Message requestMessage = mb1.CreateStartNeighborhoodInitializationRequest((uint)profileServer.PrimaryPort, (uint)profileServer.ServerNeighborPort);
                await client1.SendMessageAsync(requestMessage);

                Message responseMessage = await client1.ReceiveMessageAsync();

                bool idOk     = responseMessage.Id == requestMessage.Id;
                bool statusOk = responseMessage.Response.Status == Status.Ok;
                bool startNeighborhoodInitializationOk = idOk && statusOk;


                // Wait for update request.
                Message serverRequestMessage  = null;
                Message clientResponseMessage = null;

                List <SharedProfileAddItem> receivedItems = new List <SharedProfileAddItem>();
                bool error = false;
                while (!error)
                {
                    serverRequestMessage = await client1.ReceiveMessageAsync();

                    bool isNspUpdate = serverRequestMessage.MessageTypeCase == Message.MessageTypeOneofCase.Request &&
                                       serverRequestMessage.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest &&
                                       serverRequestMessage.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate;

                    bool isNspFinish = serverRequestMessage.MessageTypeCase == Message.MessageTypeOneofCase.Request &&
                                       serverRequestMessage.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest &&
                                       serverRequestMessage.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.FinishNeighborhoodInitialization;

                    if (isNspFinish)
                    {
                        break;
                    }

                    if (!isNspUpdate)
                    {
                        error = true;
                        break;
                    }

                    clientResponseMessage = mb1.CreateNeighborhoodSharedProfileUpdateResponse(serverRequestMessage);
                    await client1.SendMessageAsync(clientResponseMessage);

                    foreach (SharedProfileUpdateItem updateItem in serverRequestMessage.Request.ConversationRequest.NeighborhoodSharedProfileUpdate.Items)
                    {
                        if (updateItem.ActionTypeCase != SharedProfileUpdateItem.ActionTypeOneofCase.Add)
                        {
                            log.Trace("Received invalid update item action type '{0}'.", updateItem.ActionTypeCase);
                            error = true;
                            break;
                        }

                        log.Trace("Received profile name '{0}'.", updateItem.Add.Name);
                        receivedItems.Add(updateItem.Add);
                    }

                    if (error)
                    {
                        break;
                    }
                }

                bool step2Ok = verifyIdentityOk && startNeighborhoodInitializationOk;

                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");


                // Step 3
                log.Trace("Step 3");

                profileInitializationOk = true;
                profileCount            = 5;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (!await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        profileClient.Dispose();
                        profileInitializationOk = false;
                        break;
                    }

                    TestProfiles.Add(profileClient.Profile.Name, profileClient);
                }

                bool step3Ok = profileInitializationOk;

                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");



                // Step 4
                log.Trace("Step 4");

                await client2.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                verifyIdentityOk = await client2.VerifyIdentityAsync();

                // Start neighborhood initialization process.
                requestMessage = mb1.CreateStartNeighborhoodInitializationRequest((uint)profileServer.PrimaryPort, (uint)profileServer.ServerNeighborPort);
                await client2.SendMessageAsync(requestMessage);

                responseMessage = await client2.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.ErrorAlreadyExists;
                startNeighborhoodInitializationOk = idOk && statusOk;

                client2.CloseConnection();

                bool step4Ok = verifyIdentityOk && startNeighborhoodInitializationOk;

                log.Trace("Step 4: {0}", step4Ok ? "PASSED" : "FAILED");


                // Step 5
                log.Trace("Step 5");

                clientResponseMessage = mb1.CreateFinishNeighborhoodInitializationResponse(serverRequestMessage);
                await client1.SendMessageAsync(clientResponseMessage);

                client1.CloseConnection();

                await Task.Delay(20000);

                bool step5Ok = !error;

                log.Trace("Step 5: {0}", step5Ok ? "PASSED" : "FAILED");


                // Step 6
                log.Trace("Step 6");

                // Meanwhile we expect updates to arrive on our simulated profile server.
                error = false;
                List <IncomingServerMessage> psMessages = profileServer.GetMessageList();
                foreach (IncomingServerMessage ism in psMessages)
                {
                    if (ism.Role != ServerRole.ServerNeighbor)
                    {
                        continue;
                    }
                    Message message = ism.IncomingMessage;

                    if ((message.MessageTypeCase == Message.MessageTypeOneofCase.Request) &&
                        (message.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest) &&
                        (message.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate))
                    {
                        foreach (SharedProfileUpdateItem updateItem in message.Request.ConversationRequest.NeighborhoodSharedProfileUpdate.Items)
                        {
                            if (updateItem.ActionTypeCase == SharedProfileUpdateItem.ActionTypeOneofCase.Add)
                            {
                                SharedProfileAddItem addItem = updateItem.Add;
                                receivedItems.Add(addItem);
                                log.Trace("Received profile name '{0}'.", updateItem.Add.Name);
                            }
                            else
                            {
                                log.Trace("Received invalid update action type {0}.", updateItem.ActionTypeCase);
                                error = true;
                                break;
                            }
                        }
                    }

                    if (error)
                    {
                        break;
                    }
                }


                bool receivedUpdatesOk = !error;
                bool profilesOk        = client1.CheckProfileListMatchAddItems(TestProfiles, receivedItems);
                bool step6Ok           = receivedUpdatesOk && profilesOk;

                log.Trace("Step 6: {0}", step6Ok ? "PASSED" : "FAILED");


                Passed = step1Ok && step2Ok && step3Ok && step4Ok && step5Ok && step6Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client1.Dispose();
            client2.Dispose();

            foreach (ProtocolClient protocolClient in TestProfiles.Values)
            {
                protocolClient.Dispose();
            }

            if (profileServer != null)
            {
                profileServer.Shutdown();
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
コード例 #7
0
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1})", ServerIp, PrimaryPort);

            bool res = false;

            Passed = false;

            ProtocolClient client = new ProtocolClient();

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");
                // Get port list.
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client.ListServerPorts(rolePorts);

                client.CloseConnection();


                bool   profileInitializationOk = true;
                byte[] testImageData           = File.ReadAllBytes(Path.Combine("images", TestName + ".jpg"));

                for (int i = 0; i < ProfileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(i, testImageData);
                    if (await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        TestProfiles.Add(profileClient.Profile.Name, profileClient);
                    }
                    else
                    {
                        profileInitializationOk = false;
                        break;
                    }
                }

                bool step1Ok = listPortsOk && profileInitializationOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");



                // Step 2
                log.Trace("Step 2");
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool neighborhoodInitializationProcessOk = await client.NeighborhoodInitializationProcessAsync(1, 1, TestProfiles);

                // Step 2 Acceptance
                bool step2Ok = neighborhoodInitializationProcessOk;

                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");


                Passed = step1Ok && step2Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }

            foreach (ProtocolClient protocolClient in TestProfiles.Values)
            {
                protocolClient.Dispose();
            }

            client.Dispose();


            log.Trace("(-):{0}", res);
            return(res);
        }
コード例 #8
0
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];
            int       BasePort    = (int)ArgumentValues["Base Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1},BasePort:{2})", ServerIp, PrimaryPort, BasePort);

            bool res = false;

            Passed = false;

            ProtocolClient client        = new ProtocolClient();
            ProfileServer  profileServer = null;

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");
                // Get port list.
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client.ListServerPorts(rolePorts);

                client.CloseConnection();


                bool   profileInitializationOk = true;
                byte[] testImageData           = File.ReadAllBytes(Path.Combine("images", TestName + ".jpg"));
                byte[] testImageData2          = File.ReadAllBytes(Path.Combine("images", TestName + "b.png"));

                int profileIndex = 1;
                int profileCount = 50;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        TestProfiles.Add(profileClient.Profile.Name, profileClient);
                    }
                    else
                    {
                        profileClient.Dispose();
                        profileInitializationOk = false;
                        break;
                    }
                }


                profileServer = new ProfileServer("TestServer", ServerIp, BasePort, client.GetIdentityKeys());
                bool serverStartOk = profileServer.Start();

                bool step1Ok = listPortsOk && profileInitializationOk && serverStartOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");



                // Step 2
                log.Trace("Step 2");
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool neighborhoodInitializationProcessOk = await client.NeighborhoodInitializationProcessAsync(profileServer.PrimaryPort, profileServer.ServerNeighborPort, TestProfiles);

                client.CloseConnection();

                bool step2Ok = neighborhoodInitializationProcessOk;

                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");


                // Step 3
                log.Trace("Step 3");

                // Add 15 more identities.
                Dictionary <string, ProtocolClient> newProfiles = new Dictionary <string, ProtocolClient>(StringComparer.Ordinal);
                profileInitializationOk = true;
                profileCount            = 15;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        TestProfiles.Add(profileClient.Profile.Name, profileClient);
                        newProfiles.Add(profileClient.Profile.Name, profileClient);
                    }
                    else
                    {
                        profileClient.Dispose();
                        profileInitializationOk = false;
                        break;
                    }
                }

                log.Trace("Waiting 20 seconds ...");
                await Task.Delay(20000);

                // Meanwhile we expect updates to arrive on our simulated profile server.
                bool error = false;
                List <IncomingServerMessage> psMessages = profileServer.GetMessageList();
                List <SharedProfileAddItem>  addUpdates = new List <SharedProfileAddItem>();
                foreach (IncomingServerMessage ism in psMessages)
                {
                    if (ism.Role != ServerRole.ServerNeighbor)
                    {
                        continue;
                    }
                    Message message = ism.IncomingMessage;

                    if ((message.MessageTypeCase == Message.MessageTypeOneofCase.Request) &&
                        (message.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest) &&
                        (message.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate))
                    {
                        foreach (SharedProfileUpdateItem updateItem in message.Request.ConversationRequest.NeighborhoodSharedProfileUpdate.Items)
                        {
                            if (updateItem.ActionTypeCase == SharedProfileUpdateItem.ActionTypeOneofCase.Add)
                            {
                                SharedProfileAddItem addItem = updateItem.Add;
                                addUpdates.Add(addItem);
                            }
                            else
                            {
                                log.Trace("Received invalid update action type {0}.", updateItem.ActionTypeCase);
                                error = true;
                                break;
                            }
                        }
                    }

                    if (error)
                    {
                        break;
                    }
                }

                bool receivedUpdatesOk = !error;

                bool updatesOk = client.CheckProfileListMatchAddItems(newProfiles, addUpdates);

                bool step3Ok = profileInitializationOk && receivedUpdatesOk && updatesOk;

                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");



                // Step 4
                log.Trace("Step 4");

                // Cancel 15 identities.
                HashSet <byte[]> cancelledProfiles  = new HashSet <byte[]>(StructuralEqualityComparer <byte[]> .Default);
                bool             profileCancelingOk = true;
                profileCount = 15;
                for (int i = 0; i < profileCount; i++)
                {
                    int            index         = Rng.Next(TestProfiles.Count);
                    List <string>  keys          = TestProfiles.Keys.ToList();
                    ProtocolClient profileClient = TestProfiles[keys[index]];

                    if (await profileClient.CancelHostingAgreementAsync(ServerIp, (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        TestProfiles.Remove(keys[index]);
                        cancelledProfiles.Add(profileClient.GetIdentityId());
                    }
                    else
                    {
                        profileCancelingOk = false;
                        break;
                    }
                }

                await Task.Delay(20000);

                // Meanwhile we expect updates to arrive on our simulated profile server.
                psMessages = profileServer.GetMessageList();
                List <SharedProfileDeleteItem> deleteUpdates = new List <SharedProfileDeleteItem>();
                foreach (IncomingServerMessage ism in psMessages)
                {
                    if (ism.Role != ServerRole.ServerNeighbor)
                    {
                        continue;
                    }
                    Message message = ism.IncomingMessage;

                    if ((message.MessageTypeCase == Message.MessageTypeOneofCase.Request) &&
                        (message.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest) &&
                        (message.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate))
                    {
                        foreach (SharedProfileUpdateItem updateItem in message.Request.ConversationRequest.NeighborhoodSharedProfileUpdate.Items)
                        {
                            if (updateItem.ActionTypeCase == SharedProfileUpdateItem.ActionTypeOneofCase.Delete)
                            {
                                SharedProfileDeleteItem deleteItem = updateItem.Delete;
                                deleteUpdates.Add(deleteItem);
                            }
                            else
                            {
                                log.Trace("Received invalid update action type {0}.", updateItem.ActionTypeCase);
                                error = true;
                                break;
                            }
                        }
                    }

                    if (error)
                    {
                        break;
                    }
                }

                receivedUpdatesOk = !error;

                updatesOk = client.CheckProfileListMatchDeleteItems(cancelledProfiles, deleteUpdates);

                bool step4Ok = profileCancelingOk && receivedUpdatesOk && updatesOk;

                log.Trace("Step 4: {0}", step4Ok ? "PASSED" : "FAILED");



                // Step 5
                log.Trace("Step 5");

                // Change 25 profiles.
                Dictionary <byte[], SharedProfileChangeItem> changedProfiles = new Dictionary <byte[], SharedProfileChangeItem>(StructuralEqualityComparer <byte[]> .Default);
                bool profileChangingOk = true;
                profileCount = 25;
                for (int i = 0; i < profileCount; i++)
                {
                    int            index         = Rng.Next(TestProfiles.Count);
                    List <string>  keys          = TestProfiles.Keys.ToList();
                    ProtocolClient profileClient = TestProfiles[keys[index]];
                    if (changedProfiles.ContainsKey(profileClient.GetIdentityId()))
                    {
                        // Do not take one client twice.
                        i--;
                        continue;
                    }

                    SharedProfileChangeItem changeItem = new SharedProfileChangeItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(profileClient.GetIdentityId()),
                        SetName           = Rng.NextDouble() < 0.20,
                        SetLocation       = Rng.NextDouble() < 0.20,
                        SetExtraData      = Rng.NextDouble() < 0.20,
                        SetThumbnailImage = Rng.NextDouble() < 0.20,
                        SetVersion        = false,
                    };

                    // Make sure we change at least one thing.
                    if (!changeItem.SetName && !changeItem.SetLocation && !changeItem.SetThumbnailImage)
                    {
                        changeItem.SetExtraData = true;
                    }

                    if (changeItem.SetName)
                    {
                        log.Trace("Changing name of identity name '{0}'.", profileClient.Profile.Name);
                        TestProfiles.Remove(profileClient.Profile.Name);

                        profileClient.Profile.Name += "-change";
                        changeItem.Name             = profileClient.Profile.Name;
                        TestProfiles.Add(profileClient.Profile.Name, profileClient);
                    }

                    if (changeItem.SetLocation)
                    {
                        log.Trace("Changing location of identity name '{0}'.", profileClient.Profile.Name);
                        if (Rng.NextDouble() < 0.30)
                        {
                            profileClient.Profile.Location.Latitude = profileClient.Profile.Location.Latitude / 2 + 1;
                        }
                        else if (Rng.NextDouble() < 0.30)
                        {
                            profileClient.Profile.Location.Longitude = profileClient.Profile.Location.Latitude / 2 + 1;
                        }
                        else
                        {
                            profileClient.Profile.Location.Latitude  = profileClient.Profile.Location.Latitude / 2 + 1;
                            profileClient.Profile.Location.Longitude = profileClient.Profile.Location.Latitude / 2 + 1;
                        }
                        changeItem.Latitude  = profileClient.Profile.Location.GetLocationTypeLatitude();
                        changeItem.Longitude = profileClient.Profile.Location.GetLocationTypeLongitude();
                    }

                    if (changeItem.SetExtraData)
                    {
                        log.Trace("Changing extra data of identity name '{0}'.", profileClient.Profile.Name);
                        if (!string.IsNullOrEmpty(profileClient.Profile.ExtraData))
                        {
                            profileClient.Profile.ExtraData = profileClient.Profile.ExtraData.Substring(0, Math.Min(10, profileClient.Profile.ExtraData.Length)) + "-change";
                        }
                        else
                        {
                            profileClient.Profile.ExtraData = "new value";
                        }
                        changeItem.ExtraData = profileClient.Profile.ExtraData;
                    }

                    if (changeItem.SetThumbnailImage)
                    {
                        log.Trace("Changing profile image of identity name '{0}'.", profileClient.Profile.Name);
                        profileClient.Profile.ProfileImage   = testImageData2;
                        profileClient.Profile.ThumbnailImage = testImageData2;
                        changeItem.ThumbnailImage            = ProtocolHelper.ByteArrayToByteString(testImageData2);
                    }

                    changedProfiles.Add(profileClient.GetIdentityId(), changeItem);

                    await profileClient.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClCustomer], true);

                    bool ccheckInOk = await profileClient.CheckInAsync();

                    Message clientRequest = profileClient.MessageBuilder.CreateUpdateProfileRequest(null, changeItem.SetName ? changeItem.Name : null, changeItem.SetThumbnailImage ? profileClient.Profile.ProfileImage : null, changeItem.SetLocation ? profileClient.Profile.Location : null, changeItem.SetExtraData ? changeItem.ExtraData : null);
                    await profileClient.SendMessageAsync(clientRequest);

                    Message clientResponse = await profileClient.ReceiveMessageAsync();

                    bool cidOk     = clientResponse.Id == clientRequest.Id;
                    bool cstatusOk = clientResponse.Response.Status == Status.Ok;

                    profileClient.CloseConnection();

                    bool changeOk = ccheckInOk && cidOk && cstatusOk;

                    if (!changeOk)
                    {
                        profileChangingOk = false;
                        break;
                    }
                }

                await Task.Delay(20000);

                // Meanwhile we expect updates to arrive on our simulated profile server.
                psMessages = profileServer.GetMessageList();
                List <SharedProfileChangeItem> changeUpdates = new List <SharedProfileChangeItem>();
                foreach (IncomingServerMessage ism in psMessages)
                {
                    if (ism.Role != ServerRole.ServerNeighbor)
                    {
                        continue;
                    }
                    Message message = ism.IncomingMessage;

                    if ((message.MessageTypeCase == Message.MessageTypeOneofCase.Request) &&
                        (message.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest) &&
                        (message.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate))
                    {
                        foreach (SharedProfileUpdateItem updateItem in message.Request.ConversationRequest.NeighborhoodSharedProfileUpdate.Items)
                        {
                            if (updateItem.ActionTypeCase == SharedProfileUpdateItem.ActionTypeOneofCase.Change)
                            {
                                SharedProfileChangeItem changeItem = updateItem.Change;
                                changeUpdates.Add(changeItem);
                            }
                            else
                            {
                                log.Trace("Received invalid update action type {0}.", updateItem.ActionTypeCase);
                                error = true;
                                break;
                            }
                        }
                    }

                    if (error)
                    {
                        break;
                    }
                }

                receivedUpdatesOk = !error;

                updatesOk = client.CheckProfileListMatchChangeItems(changedProfiles, changeUpdates);

                bool step5Ok = profileChangingOk && receivedUpdatesOk && updatesOk;

                log.Trace("Step 5: {0}", step5Ok ? "PASSED" : "FAILED");



                // Step 6
                log.Trace("Step 6");

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool verifyIdentityOk = await client.VerifyIdentityAsync();

                Message request = mb.CreateStopNeighborhoodUpdatesRequest();
                await client.SendMessageAsync(request);

                Message response = await client.ReceiveMessageAsync();

                bool idOk          = response.Id == request.Id;
                bool statusOk      = response.Response.Status == Status.Ok;
                bool stopUpdatesOk = idOk && statusOk;

                client.CloseConnection();

                bool step6Ok = verifyIdentityOk && stopUpdatesOk;

                log.Trace("Step 6: {0}", step6Ok ? "PASSED" : "FAILED");



                // Step 7
                log.Trace("Step 7");

                // Add 5 more identities.
                profileCount = 5;
                error        = false;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (!await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        log.Trace("Failed to register and initialize client #{0}.", i);
                        profileClient.Dispose();
                        error = true;
                        break;
                    }

                    TestProfiles.Add(profileClient.Profile.Name, profileClient);
                }

                bool addProfilesOk = !error;


                // Cancel 5 identities.
                error        = false;
                profileCount = 5;
                for (int i = 0; i < profileCount; i++)
                {
                    int            index         = Rng.Next(TestProfiles.Count);
                    List <string>  keys          = TestProfiles.Keys.ToList();
                    ProtocolClient profileClient = TestProfiles[keys[index]];

                    if (!await profileClient.CancelHostingAgreementAsync(ServerIp, (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        log.Trace("Failed to cancel hosting agreement of client name '{0}'.", profileClient.Profile.Name);
                        error = true;
                        break;
                    }

                    TestProfiles.Remove(keys[index]);
                }

                bool cancelProfilesOk = !error;



                // Change 5 profiles.
                error        = false;
                profileCount = 5;
                for (int i = 0; i < profileCount; i++)
                {
                    int            index         = Rng.Next(TestProfiles.Count);
                    List <string>  keys          = TestProfiles.Keys.ToList();
                    ProtocolClient profileClient = TestProfiles[keys[index]];

                    SharedProfileChangeItem changeItem = new SharedProfileChangeItem()
                    {
                        IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(profileClient.GetIdentityId()),
                        SetExtraData      = true,
                        ExtraData         = "last change",
                        SetVersion        = false,
                        SetLocation       = false,
                        SetName           = false,
                        SetThumbnailImage = false,
                    };

                    profileClient.Profile.ExtraData = changeItem.ExtraData;

                    await profileClient.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClCustomer], true);

                    bool checkInOk = await profileClient.CheckInAsync();

                    Message clientRequest = profileClient.MessageBuilder.CreateUpdateProfileRequest(null, null, null, null, changeItem.ExtraData);
                    await profileClient.SendMessageAsync(clientRequest);

                    Message clientResponse = await profileClient.ReceiveMessageAsync();

                    bool cidOk     = clientResponse.Id == clientRequest.Id;
                    bool cstatusOk = clientResponse.Response.Status == Status.Ok;

                    profileClient.CloseConnection();

                    bool changeOk = checkInOk && cidOk && cstatusOk;

                    if (!changeOk)
                    {
                        log.Trace("Failed to change profile of client name '{0}'.", profileClient.Profile.Name);
                        error = true;
                        break;
                    }
                }

                bool changeProfileOk = !error;

                await Task.Delay(20000);

                // Meanwhile we expect NO update messages to arrive on our simulated profile server.
                error      = false;
                psMessages = profileServer.GetMessageList();
                foreach (IncomingServerMessage ism in psMessages)
                {
                    if (ism.Role != ServerRole.ServerNeighbor)
                    {
                        continue;
                    }
                    Message message = ism.IncomingMessage;

                    if ((message.MessageTypeCase == Message.MessageTypeOneofCase.Request) &&
                        (message.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest) &&
                        (message.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate))
                    {
                        error = true;
                        break;
                    }
                }
                bool noNewUpdatesOk = !error;


                bool step7Ok = addProfilesOk && cancelProfilesOk && changeProfileOk && noNewUpdatesOk;

                log.Trace("Step 7: {0}", step7Ok ? "PASSED" : "FAILED");



                // Step 8
                log.Trace("Step 8");

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                verifyIdentityOk = await client.VerifyIdentityAsync();

                request = mb.CreateStartNeighborhoodInitializationRequest((uint)profileServer.PrimaryPort, (uint)profileServer.ServerNeighborPort);
                await client.SendMessageAsync(request);

                response = await client.ReceiveMessageAsync();

                idOk     = response.Id == request.Id;
                statusOk = response.Response.Status == Status.Ok;
                bool startNeighborhoodInitializationOk = idOk && statusOk;

                bool step8Ok = verifyIdentityOk && startNeighborhoodInitializationOk;

                log.Trace("Step 8: {0}", step8Ok ? "PASSED" : "FAILED");



                // Step 9
                log.Trace("Step 9");

                // Add 5 more identities.
                // These identities may or may not be included in the current initialization process in progress.
                List <ProtocolClient> newClients = new List <ProtocolClient>();
                profileCount = 5;
                error        = false;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (!await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        log.Trace("Failed to register and initialize client #{0}.", i);
                        profileClient.Dispose();
                        error = true;
                        break;
                    }

                    newClients.Add(profileClient);
                }

                addProfilesOk = !error;

                bool step9Ok = addProfilesOk;

                log.Trace("Step 9: {0}", step9Ok ? "PASSED" : "FAILED");



                // Step 10
                log.Trace("Step 10");


                // Wait for update request.
                Message serverRequestMessage  = null;
                Message clientResponseMessage = null;
                bool    typeOk = false;

                List <SharedProfileAddItem> receivedItems = new List <SharedProfileAddItem>();

                error = false;
                while (receivedItems.Count < TestProfiles.Count)
                {
                    serverRequestMessage = await client.ReceiveMessageAsync();

                    typeOk = serverRequestMessage.MessageTypeCase == Message.MessageTypeOneofCase.Request &&
                             serverRequestMessage.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest &&
                             serverRequestMessage.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate;

                    clientResponseMessage = mb.CreateNeighborhoodSharedProfileUpdateResponse(serverRequestMessage);
                    await client.SendMessageAsync(clientResponseMessage);


                    if (!typeOk)
                    {
                        break;
                    }

                    foreach (SharedProfileUpdateItem updateItem in serverRequestMessage.Request.ConversationRequest.NeighborhoodSharedProfileUpdate.Items)
                    {
                        if (updateItem.ActionTypeCase != SharedProfileUpdateItem.ActionTypeOneofCase.Add)
                        {
                            log.Trace("Received invalid update item action type '{0}'.", updateItem.ActionTypeCase);
                            error = true;
                            break;
                        }

                        receivedItems.Add(updateItem.Add);
                    }

                    if (error)
                    {
                        break;
                    }
                }

                log.Trace("Received {0} profiles from target profile server.", receivedItems.Count);

                bool receivedProfilesOk = false;
                if (!error)
                {
                    // As we do not know if new identities made it to the initialization process, we just try all possible combinations.
                    // First possibility is that no new clients were present in the process.
                    if (client.CheckProfileListMatchAddItems(TestProfiles, receivedItems))
                    {
                        receivedProfilesOk = true;
                    }

                    for (int i = 0; i < newClients.Count; i++)
                    {
                        ProtocolClient newClient = newClients[i];
                        TestProfiles.Add(newClient.Profile.Name, newClient);

                        // Other possibilities are that one or more clients were present in the process.
                        if (!receivedProfilesOk)
                        {
                            if (client.CheckProfileListMatchAddItems(TestProfiles, receivedItems))
                            {
                                receivedProfilesOk = true;
                            }
                        }
                    }
                }

                bool step10Ok = receivedProfilesOk;

                log.Trace("Step 10: {0}", step10Ok ? "PASSED" : "FAILED");



                // Step 11
                log.Trace("Step 11");

                // Add 5 more identities.
                profileCount = 5;
                error        = false;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (!await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        log.Trace("Failed to register and initialize client #{0}.", i);
                        profileClient.Dispose();
                        error = true;
                        break;
                    }

                    TestProfiles.Add(profileClient.Profile.Name, profileClient);
                }

                addProfilesOk = !error;

                bool step11Ok = addProfilesOk;

                log.Trace("Step 11: {0}", step11Ok ? "PASSED" : "FAILED");



                // Step 12
                log.Trace("Step 12");

                client.CloseConnection();
                bool step12Ok = true;

                log.Trace("Step 12: {0}", step12Ok ? "PASSED" : "FAILED");



                // Step 13
                log.Trace("Step 13");

                // Add 5 more identities.
                profileCount = 5;
                error        = false;
                for (int i = 0; i < profileCount; i++)
                {
                    ProtocolClient profileClient = new ProtocolClient();
                    profileClient.InitializeRandomProfile(profileIndex, testImageData);
                    profileIndex++;

                    if (!await profileClient.RegisterAndInitializeProfileAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], (int)rolePorts[ServerRoleType.ClCustomer]))
                    {
                        log.Trace("Failed to register and initialize client #{0}.", i);
                        profileClient.Dispose();
                        error = true;
                        break;
                    }

                    TestProfiles.Add(profileClient.Profile.Name, profileClient);
                }

                addProfilesOk = !error;

                await Task.Delay(20000);

                // Meanwhile we expect NO update messages to arrive on our simulated profile server.
                error      = false;
                psMessages = profileServer.GetMessageList();
                foreach (IncomingServerMessage ism in psMessages)
                {
                    if (ism.Role != ServerRole.ServerNeighbor)
                    {
                        continue;
                    }
                    Message message = ism.IncomingMessage;

                    if ((message.MessageTypeCase == Message.MessageTypeOneofCase.Request) &&
                        (message.Request.ConversationTypeCase == Request.ConversationTypeOneofCase.ConversationRequest) &&
                        (message.Request.ConversationRequest.RequestTypeCase == ConversationRequest.RequestTypeOneofCase.NeighborhoodSharedProfileUpdate))
                    {
                        error = true;
                        break;
                    }
                }
                noNewUpdatesOk = !error;

                bool step13Ok = addProfilesOk && noNewUpdatesOk;

                log.Trace("Step 13: {0}", step13Ok ? "PASSED" : "FAILED");



                Passed = step1Ok && step2Ok && step3Ok && step4Ok && step5Ok && step6Ok && step7Ok && step8Ok && step9Ok && step10Ok && step11Ok && step12Ok && step13Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();

            foreach (ProtocolClient protocolClient in TestProfiles.Values)
            {
                protocolClient.Dispose();
            }

            if (profileServer != null)
            {
                profileServer.Shutdown();
            }

            log.Trace("(-):{0}", res);
            return(res);
        }
コード例 #9
0
        /// <summary>
        /// Implementation of the test itself.
        /// </summary>
        /// <returns>true if the test passes, false otherwise.</returns>
        public override async Task <bool> RunAsync()
        {
            IPAddress ServerIp    = (IPAddress)ArgumentValues["Server IP"];
            int       PrimaryPort = (int)ArgumentValues["primary Port"];
            int       BasePort    = (int)ArgumentValues["Base Port"];
            int       LocPort     = (int)ArgumentValues["LOC Port"];

            log.Trace("(ServerIp:'{0}',PrimaryPort:{1},BasePort:{2},LocPort:{3})", ServerIp, PrimaryPort, BasePort, LocPort);

            bool res = false;

            Passed = false;

            ProtocolClient client        = new ProtocolClient();
            ProfileServer  profileServer = null;
            LocServer      locServer     = null;

            try
            {
                MessageBuilder mb = client.MessageBuilder;

                // Step 1
                log.Trace("Step 1");

                // Get port list.
                await client.ConnectAsync(ServerIp, PrimaryPort, false);

                Dictionary <ServerRoleType, uint> rolePorts = new Dictionary <ServerRoleType, uint>();
                bool listPortsOk = await client.ListServerPorts(rolePorts);

                client.CloseConnection();

                // Create identities.
                int    profileNumber = 0;
                byte[] imageData     = File.ReadAllBytes(Path.Combine("images", TestName + ".png"));

                Dictionary <string, ProtocolClient> expectedLastClients = new Dictionary <string, ProtocolClient>(StringComparer.Ordinal);
                List <string> excessClientNames = new List <string>();
                for (int i = 0; i < 20050; i++)
                {
                    ProtocolClient protocolClient = new ProtocolClient();
                    protocolClient.InitializeRandomProfile(profileNumber, imageData);
                    profileNumber++;
                    if (i >= 19990)
                    {
                        protocolClient.Profile.Type = "last";
                        if (i < 20000)
                        {
                            expectedLastClients.Add(protocolClient.Profile.Name, protocolClient);
                        }
                        else
                        {
                            excessClientNames.Add(protocolClient.Profile.Name);
                        }
                    }
                    TestProfiles.Add(protocolClient.Profile.Name, protocolClient);
                }


                // Start simulated profile server.
                profileServer = new ProfileServer("TestProfileServer", ServerIp, BasePort, client.GetIdentityKeys(), new GpsLocation(1, 2));
                bool profileServerStartOk = profileServer.Start();

                // Start simulated LOC server.
                locServer = new LocServer("TestLocServer", ServerIp, LocPort);
                bool locServerStartOk = locServer.Start();

                await locServer.WaitForProfileServerConnectionAsync();

                bool step1Ok = profileServerStartOk && locServerStartOk;
                log.Trace("Step 1: {0}", step1Ok ? "PASSED" : "FAILED");


                // Step 2
                log.Trace("Step 2");

                // Announce new neighbor.
                Iop.Locnet.NeighbourhoodChange change = new Iop.Locnet.NeighbourhoodChange()
                {
                    AddedNodeInfo = profileServer.GetNodeInfo(LocPort)
                };

                bool changeNotificationOk = await locServer.SendChangeNotification(change);

                // Wait for start of neighborhood initialization process.
                IncomingServerMessage incomingServerMessage = await profileServer.WaitForConversationRequest(ServerRole.ServerNeighbor, ConversationRequest.RequestTypeOneofCase.StartNeighborhoodInitialization);


                // Send update.
                bool statusOk     = false;
                bool updateOk     = true;
                int  profilesSent = 0;
                List <ProtocolClient> allProfiles    = new List <ProtocolClient>(TestProfiles.Values);
                List <ProtocolClient> profilesToSend = allProfiles.GetRange(0, 19990);
                while (profilesToSend.Count > 0)
                {
                    int batchSize = Math.Min(Rng.Next(100, 150), profilesToSend.Count);

                    List <SharedProfileUpdateItem> updateItems = new List <SharedProfileUpdateItem>();
                    foreach (ProtocolClient pc in profilesToSend.GetRange(0, batchSize))
                    {
                        updateItems.Add(pc.GetSharedProfileUpdateAddItem());
                    }

                    profilesToSend.RemoveRange(0, batchSize);

                    Message updateRequest = await profileServer.SendNeighborhoodSharedProfileUpdateRequest(incomingServerMessage.Client, updateItems);

                    profilesSent         += batchSize;
                    incomingServerMessage = await profileServer.WaitForResponse(ServerRole.ServerNeighbor, updateRequest);

                    statusOk = incomingServerMessage.IncomingMessage.Response.Status == Status.Ok;
                    bool batchOk = (updateRequest != null) && statusOk;
                    if (!batchOk)
                    {
                        updateOk = false;
                        break;
                    }
                }


                // Finish neighborhood initialization process.
                Message finishRequest = await profileServer.SendFinishNeighborhoodInitializationRequest(incomingServerMessage.Client);

                incomingServerMessage = await profileServer.WaitForResponse(ServerRole.ServerNeighbor, finishRequest);

                statusOk = incomingServerMessage.IncomingMessage.Response.Status == Status.Ok;
                bool finishOk = (finishRequest != null) && statusOk;


                bool step2Ok = changeNotificationOk && updateOk && finishOk;
                log.Trace("Step 2: {0}", step2Ok ? "PASSED" : "FAILED");



                // Step 3
                log.Trace("Step 3");

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                bool verifyIdentityOk = await client.VerifyIdentityAsync();

                List <SharedProfileUpdateItem> badUpdateItems = new List <SharedProfileUpdateItem>();
                foreach (ProtocolClient pc in allProfiles.GetRange(19990, 60))
                {
                    badUpdateItems.Add(pc.GetSharedProfileUpdateAddItem());
                }


                Message requestMessage = mb.CreateNeighborhoodSharedProfileUpdateRequest(badUpdateItems);
                await client.SendMessageAsync(requestMessage);

                Message responseMessage = await client.ReceiveMessageAsync();

                bool idOk = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.ErrorInvalidValue;
                bool detailsOk = responseMessage.Response.Details == "10.add";

                bool badUpdateOk = idOk && statusOk && detailsOk;
                client.CloseConnection();

                // Step 3 Acceptance
                bool step3Ok = verifyIdentityOk && badUpdateOk;

                log.Trace("Step 3: {0}", step3Ok ? "PASSED" : "FAILED");



                // Step 4
                log.Trace("Step 4");

                // Start conversation.
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], true);

                bool startConversationOk = await client.StartConversationAsync();

                HashSet <byte[]> expectedCoveredServers = new HashSet <byte[]>(StructuralEqualityComparer <byte[]> .Default)
                {
                    client.GetIdentityId(), Crypto.Sha256(client.ServerKey)
                };

                // Search all profiles with type "last".
                requestMessage = mb.CreateProfileSearchRequest("last", null, null, null, 0, 100, 100);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;


                bool totalRecordCountOk       = responseMessage.Response.ConversationResponse.ProfileSearch.TotalRecordCount == 10;
                bool maxResponseRecordCountOk = responseMessage.Response.ConversationResponse.ProfileSearch.MaxResponseRecordCount == 100;
                bool profilesCountOk          = responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.Count == 10;
                bool resultsOk = client.CheckProfileListMatchSearchResultItems(expectedLastClients, responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.ToList(), false, false, client.GetIdentityId(), true);

                bool queryOk = idOk && statusOk && totalRecordCountOk && maxResponseRecordCountOk && profilesCountOk && resultsOk;

                client.CloseConnection();

                // Step 4 Acceptance
                bool step4Ok = startConversationOk && queryOk;

                log.Trace("Step 4: {0}", step4Ok ? "PASSED" : "FAILED");



                // Step 5
                log.Trace("Step 5");

                // Make TestProfiles reflect the status on the target profile server.
                foreach (string excessClientName in excessClientNames)
                {
                    TestProfiles[excessClientName].Dispose();
                    TestProfiles.Remove(excessClientName);
                }

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                verifyIdentityOk = await client.VerifyIdentityAsync();

                // Select 140 profiles for deletion.
                List <SharedProfileUpdateItem> deleteUpdateItems = new List <SharedProfileUpdateItem>();
                while (deleteUpdateItems.Count < 140)
                {
                    int            index = Rng.Next(TestProfiles.Count);
                    ProtocolClient pc    = TestProfiles.ElementAt(index).Value;
                    deleteUpdateItems.Add(pc.GetSharedProfileUpdateDeleteItem());

                    if (expectedLastClients.ContainsKey(pc.Profile.Name))
                    {
                        expectedLastClients.Remove(pc.Profile.Name);
                    }

                    TestProfiles.Remove(pc.Profile.Name);
                    pc.Dispose();
                }

                // Send delete update.
                requestMessage = mb.CreateNeighborhoodSharedProfileUpdateRequest(deleteUpdateItems);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;

                bool deleteUpdateOk = idOk && statusOk;


                // Generate 160 new identities.
                badUpdateItems.Clear();
                excessClientNames.Clear();
                for (int i = 0; i < 160; i++)
                {
                    ProtocolClient protocolClient = new ProtocolClient();
                    protocolClient.InitializeRandomProfile(profileNumber, imageData);
                    profileNumber++;
                    protocolClient.Profile.Type = "last";

                    if (TestProfiles.Count < 20000)
                    {
                        expectedLastClients.Add(protocolClient.Profile.Name, protocolClient);
                    }
                    else
                    {
                        excessClientNames.Add(protocolClient.Profile.Name);
                    }

                    TestProfiles.Add(protocolClient.Profile.Name, protocolClient);
                    badUpdateItems.Add(protocolClient.GetSharedProfileUpdateAddItem());
                }


                // Add the new profiles to the profile server.
                requestMessage = mb.CreateNeighborhoodSharedProfileUpdateRequest(badUpdateItems);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk      = responseMessage.Id == requestMessage.Id;
                statusOk  = responseMessage.Response.Status == Status.ErrorInvalidValue;
                detailsOk = responseMessage.Response.Details == "140.add";

                badUpdateOk = idOk && statusOk && detailsOk;
                client.CloseConnection();

                // Step 5 Acceptance
                bool step5Ok = verifyIdentityOk && deleteUpdateOk && badUpdateOk;

                log.Trace("Step 5: {0}", step5Ok ? "PASSED" : "FAILED");



                // Step 6
                log.Trace("Step 6");

                // Make TestProfiles reflect the status on the target profile server.
                foreach (string excessClientName in excessClientNames)
                {
                    TestProfiles[excessClientName].Dispose();
                    TestProfiles.Remove(excessClientName);
                }

                // Start conversation.
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], true);

                startConversationOk = await client.StartConversationAsync();

                // Search all profiles with type "last".
                requestMessage = mb.CreateProfileSearchRequest("last", null, null, null, 0, 1000, 1000, false, false);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;


                totalRecordCountOk       = responseMessage.Response.ConversationResponse.ProfileSearch.TotalRecordCount == expectedLastClients.Count;
                maxResponseRecordCountOk = responseMessage.Response.ConversationResponse.ProfileSearch.MaxResponseRecordCount == 1000;
                profilesCountOk          = responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.Count == expectedLastClients.Count;
                resultsOk = client.CheckProfileListMatchSearchResultItems(expectedLastClients, responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.ToList(), false, false, client.GetIdentityId(), false);

                queryOk = idOk && statusOk && totalRecordCountOk && maxResponseRecordCountOk && profilesCountOk && resultsOk;

                client.CloseConnection();

                // Step 6 Acceptance
                bool step6Ok = startConversationOk && queryOk;

                log.Trace("Step 6: {0}", step6Ok ? "PASSED" : "FAILED");



                // Step 7
                log.Trace("Step 7");

                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.SrNeighbor], true);

                verifyIdentityOk = await client.VerifyIdentityAsync();

                // Select 40 profiles for deletion.
                deleteUpdateItems = new List <SharedProfileUpdateItem>();
                while (deleteUpdateItems.Count < 40)
                {
                    int            index = Rng.Next(TestProfiles.Count);
                    ProtocolClient pc    = TestProfiles.ElementAt(index).Value;
                    deleteUpdateItems.Add(pc.GetSharedProfileUpdateDeleteItem());

                    if (expectedLastClients.ContainsKey(pc.Profile.Name))
                    {
                        expectedLastClients.Remove(pc.Profile.Name);
                    }

                    TestProfiles.Remove(pc.Profile.Name);
                    pc.Dispose();
                }

                // Select 40 profiles for change, but avoid updating one profile twice in a single update message, which is forbidden.
                HashSet <int> usedIndexes = new HashSet <int>();
                List <SharedProfileUpdateItem> changeUpdateItems = new List <SharedProfileUpdateItem>();
                while (changeUpdateItems.Count < 40)
                {
                    int index = Rng.Next(TestProfiles.Count);

                    if (usedIndexes.Contains(index))
                    {
                        continue;
                    }
                    usedIndexes.Add(index);

                    ProtocolClient pc = TestProfiles.ElementAt(index).Value;
                    pc.Profile.ExtraData = "1234567890";
                    SharedProfileUpdateItem changeUpdateItem = new SharedProfileUpdateItem()
                    {
                        Change = new SharedProfileChangeItem()
                        {
                            IdentityNetworkId = ProtocolHelper.ByteArrayToByteString(pc.GetIdentityId()),
                            SetExtraData      = true,
                            ExtraData         = pc.Profile.ExtraData
                        }
                    };
                    changeUpdateItems.Add(changeUpdateItem);
                }

                // Generate 40 new identities.
                List <SharedProfileUpdateItem> addUpdateItems = new List <SharedProfileUpdateItem>();
                for (int i = 0; i < 40; i++)
                {
                    ProtocolClient protocolClient = new ProtocolClient();
                    protocolClient.InitializeRandomProfile(profileNumber, imageData);
                    profileNumber++;
                    protocolClient.Profile.Type = "last";

                    expectedLastClients.Add(protocolClient.Profile.Name, protocolClient);

                    TestProfiles.Add(protocolClient.Profile.Name, protocolClient);
                    addUpdateItems.Add(protocolClient.GetSharedProfileUpdateAddItem());
                }


                // Send all the updates as one.
                List <SharedProfileUpdateItem> newUpdateItems = new List <SharedProfileUpdateItem>();
                newUpdateItems.AddRange(deleteUpdateItems);
                newUpdateItems.AddRange(changeUpdateItems);
                newUpdateItems.AddRange(addUpdateItems);
                requestMessage = mb.CreateNeighborhoodSharedProfileUpdateRequest(newUpdateItems);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;

                bool newUpdateOk = idOk && statusOk;
                client.CloseConnection();

                // Step 7 Acceptance
                bool step7Ok = verifyIdentityOk && newUpdateOk;

                log.Trace("Step 7: {0}", step7Ok ? "PASSED" : "FAILED");



                // Step 8
                log.Trace("Step 8");

                // Start conversation.
                await client.ConnectAsync(ServerIp, (int)rolePorts[ServerRoleType.ClNonCustomer], true);

                startConversationOk = await client.StartConversationAsync();

                // Search all profiles with type "last".
                requestMessage = mb.CreateProfileSearchRequest("last", null, null, null, 0, 1000, 1000, false, false);
                await client.SendMessageAsync(requestMessage);

                responseMessage = await client.ReceiveMessageAsync();

                idOk     = responseMessage.Id == requestMessage.Id;
                statusOk = responseMessage.Response.Status == Status.Ok;

                totalRecordCountOk       = responseMessage.Response.ConversationResponse.ProfileSearch.TotalRecordCount == expectedLastClients.Count;
                maxResponseRecordCountOk = responseMessage.Response.ConversationResponse.ProfileSearch.MaxResponseRecordCount == 1000;
                profilesCountOk          = responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.Count == expectedLastClients.Count;
                resultsOk = client.CheckProfileListMatchSearchResultItems(expectedLastClients, responseMessage.Response.ConversationResponse.ProfileSearch.Profiles.ToList(), false, false, client.GetIdentityId(), false);

                queryOk = idOk && statusOk && totalRecordCountOk && maxResponseRecordCountOk && profilesCountOk && resultsOk;

                client.CloseConnection();

                // Step 8 Acceptance
                bool step8Ok = startConversationOk && queryOk;

                log.Trace("Step 8: {0}", step8Ok ? "PASSED" : "FAILED");


                Passed = step1Ok && step2Ok && step3Ok && step4Ok && step5Ok && step6Ok && step7Ok && step8Ok;

                res = true;
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }
            client.Dispose();

            foreach (ProtocolClient protocolClient in TestProfiles.Values)
            {
                protocolClient.Dispose();
            }

            if (profileServer != null)
            {
                profileServer.Shutdown();
            }
            if (locServer != null)
            {
                locServer.Shutdown();
            }

            log.Trace("(-):{0}", res);
            return(res);
        }