Пример #1
0
        public void Equals_Works(string systemBuid, string hostId, string otherSystemBuid, string otherHostId, bool equal, bool sameHashCode)
        {
            var record = new PairingRecord()
            {
                SystemBUID = systemBuid, HostId = hostId
            };
            var other = new PairingRecord()
            {
                SystemBUID = otherSystemBuid, HostId = otherHostId
            };

            Assert.Equal(equal, record.Equals(other));
            Assert.Equal(equal, other.Equals(record));
            Assert.Equal(equal, PairingRecord.Equals(other, record));
            Assert.Equal(equal, PairingRecord.Equals(record, other));
            Assert.Equal(equal, object.Equals(other, record));
            Assert.Equal(equal, object.Equals(record, other));

            Assert.Equal(sameHashCode, record.GetHashCode() == other.GetHashCode());
        }
Пример #2
0
        /// <summary>
        /// Asynchronously retrieves or generates a pairing record for a device.
        /// </summary>
        /// <param name="udid">
        /// The UDID of the device for which to retrieve or generate the pairing record.
        /// </param>
        /// <param name="cancellationToken">
        /// A <see cref="CancellationToken"/> which can be used to cancel the asynchronous operation.
        /// </param>
        /// <returns>
        /// A <see cref="Task"/> representing the asynchronous operation.
        /// </returns>
        public virtual async Task <PairingRecord> ProvisionPairingRecordAsync(string udid, CancellationToken cancellationToken)
        {
            // Pairing records can be stored at both the cluster level and locally. Use the first pairing record which is valid, and make sure the cluster
            // and local records are in sync.
            this.logger.LogInformation("Provisioning a pairing record for device {udid}", udid);

            var usbmuxdPairingRecord = await this.muxerClient.ReadPairingRecordAsync(udid, cancellationToken).ConfigureAwait(false);

            var kubernetesPairingRecord = await this.kubernetesPairingRecordStore.ReadAsync(udid, cancellationToken).ConfigureAwait(false);

            this.logger.LogInformation("Found pairing record {usbmuxdPairingRecord} in usbmuxd", usbmuxdPairingRecord);
            this.logger.LogInformation("Found pairing record {kubernetesPairingRecord} in Kubernetes", kubernetesPairingRecord);

            PairingRecord pairingRecord = null;

            using (var context = await this.serviceProvider.CreateDeviceScopeAsync(udid, cancellationToken).ConfigureAwait(false))
                await using (var lockdown = await context.StartServiceAsync <LockdownClient>(cancellationToken).ConfigureAwait(false))
                {
                    if (usbmuxdPairingRecord != null && await lockdown.ValidatePairAsync(usbmuxdPairingRecord, cancellationToken).ConfigureAwait(false))
                    {
                        this.logger.LogInformation("The pairing record stored in usbmuxd is valid.");
                        pairingRecord = usbmuxdPairingRecord;
                    }
                    else if (kubernetesPairingRecord != null && await lockdown.ValidatePairAsync(kubernetesPairingRecord, cancellationToken).ConfigureAwait(false))
                    {
                        this.logger.LogInformation("The pairing record stored in Kubernetes is valid.");
                        pairingRecord = kubernetesPairingRecord;
                    }
                    else
                    {
                        this.logger.LogInformation("No valid pairing record could be found.");

                        if (!this.pairingTasks.ContainsKey(udid) || this.pairingTasks[udid].IsCompleted)
                        {
                            this.logger.LogInformation("Starting a new pairing task");
                            var worker = context.ServiceProvider.GetRequiredService <PairingWorker>();
                            this.pairingTasks[udid] = worker.PairAsync(cancellationToken);
                        }

                        this.logger.LogInformation("A pairing task is running. Returning null and waiting for the device to pair with the host.");
                        return(null);
                    }
                }

            // Update outdated pairing records if required.
            if (!PairingRecord.Equals(pairingRecord, usbmuxdPairingRecord))
            {
                this.logger.LogInformation("The pairing record stored in usbmuxd for device {device} is outdated. Updating.", udid);
                if (usbmuxdPairingRecord != null)
                {
                    await this.muxerClient.DeletePairingRecordAsync(udid, cancellationToken).ConfigureAwait(false);
                }

                await this.muxerClient.SavePairingRecordAsync(udid, pairingRecord, cancellationToken).ConfigureAwait(false);

                this.logger.LogInformation("Updated the pairing record in usbmuxd for device {device}.", udid);
            }

            if (!PairingRecord.Equals(pairingRecord, kubernetesPairingRecord))
            {
                this.logger.LogInformation("The pairing record stored in the cluster for device {device} is outdated. Updating.", udid);
                if (kubernetesPairingRecord != null)
                {
                    await this.kubernetesPairingRecordStore.DeleteAsync(udid, cancellationToken).ConfigureAwait(false);
                }

                await this.kubernetesPairingRecordStore.WriteAsync(udid, pairingRecord, cancellationToken).ConfigureAwait(false);

                this.logger.LogInformation("Updated the pairing record in the cluster for device {device}.", udid);
            }

            return(pairingRecord);
        }