public void CanGetLocalCacheKeyFromRepoInfo() { List <string> repoIds = new List <string> { "df3216c6-6d33-476e-8d89-e877a6d74c79", "testId", "826847f5da3ef78114b2a9d5253ada9d95265c76" }; MockTracer tracer = new MockTracer(); MockScalarEnlistment enlistment = CreateEnlistment("mock://repoUrl"); LocalCacheResolver localCacheResolver = new LocalCacheResolver(enlistment); foreach (string repoId in repoIds) { VstsInfoData vstsInfo = new VstsInfoData(); vstsInfo.Repository = new VstsInfoData.RepositoryDetails(); vstsInfo.Repository.Id = repoId; localCacheResolver.TryGetLocalCacheKeyFromRepoInfoOrURL( tracer, vstsInfo, out string localCacheKey, out string errorMessage).ShouldBeTrue(); errorMessage.ShouldBeEmpty(); localCacheKey.ShouldEqual($"{RepoIdKeyPrefix}{repoId}"); } }
private bool TryDetermineLocalCacheAndInitializePaths(string localCacheRoot, out string errorMessage) { errorMessage = null; LocalCacheResolver localCacheResolver = new LocalCacheResolver(this.enlistment); VstsInfoData vstsInfo = this.QueryVstsInfo(this.tracer, this.enlistment, this.retryConfig); string error; string localCacheKey; if (!localCacheResolver.TryGetLocalCacheKeyFromRepoInfoOrURL( this.tracer, vstsInfo, localCacheKey: out localCacheKey, errorMessage: out error)) { errorMessage = "Error determining local cache key: " + error; return(false); } EventMetadata metadata = this.CreateEventMetadata(); metadata.Add("localCacheRoot", localCacheRoot); metadata.Add("localCacheKey", localCacheKey); metadata.Add(TracingConstants.MessageKey.InfoMessage, "Initializing cache paths"); this.tracer.RelatedEvent(EventLevel.Informational, "CloneVerb_TryDetermineLocalCacheAndInitializePaths", metadata); this.enlistment.InitializeCachePathsFromKey(localCacheRoot, localCacheKey); return(true); }
public void FallBackToUsingURLWhenRepoInfoEmpty() { MockScalarEnlistment enlistment = CreateEnlistment("mock://repoUrl"); LocalCacheResolver localCacheResolver = new LocalCacheResolver(enlistment); VstsInfoData vstsInfo = new VstsInfoData(); LocalKeyShouldBeResolvedFromURL(localCacheResolver, vstsInfo); vstsInfo.Repository = new VstsInfoData.RepositoryDetails(); LocalKeyShouldBeResolvedFromURL(localCacheResolver, vstsInfo); vstsInfo.Repository.Id = string.Empty; LocalKeyShouldBeResolvedFromURL(localCacheResolver, vstsInfo); vstsInfo.Repository.Id = " "; LocalKeyShouldBeResolvedFromURL(localCacheResolver, vstsInfo); }
protected VstsInfoData QueryVstsInfo(ITracer tracer, ScalarEnlistment enlistment, RetryConfig retryConfig) { VstsInfoData vstsInfo = null; string errorMessage = null; if (!this.ShowStatusWhileRunning( () => { using (VstsInfoHttpRequestor repoInfoRequestor = new VstsInfoHttpRequestor(tracer, enlistment, retryConfig)) { const bool LogErrors = true; return(repoInfoRequestor.TryQueryRepoInfo(LogErrors, out vstsInfo, out errorMessage)); } }, "Querying remote for repo info")) { this.ReportErrorAndExit(tracer, $"Unable to query {ScalarConstants.Endpoints.RepoInfo}" + Environment.NewLine + errorMessage); } return(vstsInfo); }
private static void LocalKeyShouldBeResolvedFromURL(LocalCacheResolver localCacheResolver, VstsInfoData vstsInfo, out string localCacheKey) { localCacheResolver.TryGetLocalCacheKeyFromRepoInfoOrURL( new MockTracer(), vstsInfo, out localCacheKey, out string errorMessage).ShouldBeTrue(); errorMessage.ShouldBeEmpty(); localCacheKey.Substring(0, UrlKeyPrefix.Length).ShouldEqual(UrlKeyPrefix); SHA1Util.IsValidShaFormat(localCacheKey.Substring(UrlKeyPrefix.Length)).ShouldBeTrue(); }
private static void LocalKeyShouldBeResolvedFromURL(LocalCacheResolver localCacheResolver, VstsInfoData vstsInfo) { LocalKeyShouldBeResolvedFromURL(localCacheResolver, vstsInfo, out _); }
public bool TryQueryRepoInfo(bool logErrors, out VstsInfoData vstsInfo, out string errorMessage) { Uri repoInfoEndpoint; if (!this.TryCreateRepoEndpointUri(this.repoUrl, ScalarConstants.Endpoints.RepoInfo, out repoInfoEndpoint, out errorMessage)) { vstsInfo = null; return(false); } long requestId = HttpRequestor.GetNewRequestId(); RetryWrapper <VstsInfoData> retrier = new RetryWrapper <VstsInfoData>(this.RetryConfig.MaxAttempts, CancellationToken.None); retrier.OnFailure += RetryWrapper <VstsInfoData> .StandardErrorHandler( this.Tracer, requestId, "QueryVstsInfo", forceLogAsWarning : true); // Not all servers support /vsts/info RetryWrapper <VstsInfoData> .InvocationResult output = retrier.Invoke( tryCount => { using (GitEndPointResponseData response = this.SendRequest( requestId, repoInfoEndpoint, HttpMethod.Get, requestContent: null, cancellationToken: CancellationToken.None)) { if (response.HasErrors) { return(new RetryWrapper <VstsInfoData> .CallbackResult(response.Error, response.ShouldRetry)); } try { string configString = response.RetryableReadToEnd(); VstsInfoData vstsInfoData = JsonConvert.DeserializeObject <VstsInfoData>( configString, new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Ignore }); return(new RetryWrapper <VstsInfoData> .CallbackResult(vstsInfoData)); } catch (JsonReaderException e) { return(new RetryWrapper <VstsInfoData> .CallbackResult(e, shouldRetry: false)); } } }); if (output.Succeeded) { vstsInfo = output.Result; errorMessage = null; return(true); } GitObjectsHttpException httpException = output.Error as GitObjectsHttpException; HttpStatusCode? httpStatusCode = httpException?.StatusCode; vstsInfo = null; EventMetadata metadata = new EventMetadata(); metadata.Add(nameof(httpStatusCode), httpStatusCode.ToString()); metadata.Add(nameof(this.IsAnonymous), this.IsAnonymous); if (httpStatusCode == HttpStatusCode.NotFound || (httpStatusCode == HttpStatusCode.Unauthorized && this.IsAnonymous)) { errorMessage = null; this.Tracer.RelatedEvent( EventLevel.Informational, $"{nameof(this.TryQueryRepoInfo)}_NoVstsInfo", metadata); // These failures are OK because not all servers support /vsts/info return(true); } metadata.Add("Exception", output.Error.ToString()); this.Tracer.RelatedError(metadata, $"{nameof(this.TryQueryRepoInfo)} failed"); errorMessage = output.Error.Message; return(false); }