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()); }
/// <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); }