chr
2026-04-05 fe750b791d5b517cc4e9bc8e99a9a75139a0cfba
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
namespace OpenTap.Engine.UnitTests
{
    [Display("Artifacts Zip")]
    public class ArtifactZipper : ResultListener, IArtifactListener
    {
        [FilePath]
        public MacroString ZipFile { get; set; } = new MacroString()
        {
            Text = "<Date>.zip"
        };
 
        public ArtifactZipper()
        {
            Name = "Zip";
        }
        
        
        public override void OnTestPlanRunStart(TestPlanRun planRun)
        {
            base.OnTestPlanRunStart(planRun);
            var fileName = GetTmpFileName(planRun);
            var fstr = File.OpenWrite(fileName);
            using var archive = new ZipArchive(fstr, ZipArchiveMode.Create, false);    
        }
 
        public override void OnTestPlanRunCompleted(TestPlanRun planRun, Stream logStream)
        {
            base.OnTestPlanRunCompleted(planRun, logStream);
            
            var fileName = GetTmpFileName(planRun);
            
            var newName = ZipFile.Expand(planRun);
            try
            {
                FileSystemHelper.EnsureDirectoryOf(newName);
                File.Move(fileName, newName);
                
            }
            catch (IOException e)
            {
                if (e.Message.Contains("already exists"))
                {
                    // try finding another name for the file.
                    var ext = Path.GetExtension(newName);
                    if (ext == null)
                    {
                        for (int i = 2; i < 20; i++)
                        {
                            var name2 = $"{newName}.{i}";
                            if (!File.Exists(name2))
                            {
                                File.Move(fileName, name2);
                                break;
                            }
                        }
                    }
                    else
                    {
                        for (int i = 2; i < 20; i++)
                        {
                            var name2 = Path.ChangeExtension(newName, $"{i}{ext}");
                            if (!File.Exists(name2))
                            {
                                File.Move(fileName, name2);
                                newName = name2;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    throw;
                }
            }
            this.Log.Debug("Wrote file: {0}", Path.GetFullPath(newName));
            
            planRun.PublishArtifactAsync(File.OpenRead(newName), Path.GetFileName(newName));
        }
 
        readonly Dictionary<Guid, Guid> parentMap = new Dictionary<Guid, Guid>();
        
        public override void OnTestStepRunStart(TestStepRun stepRun)
        {
            base.OnTestStepRunStart(stepRun);
            parentMap.Add(stepRun.Id, stepRun.Parent);
        }
 
        public override void OnTestStepRunCompleted(TestStepRun stepRun)
        {
            base.OnTestStepRunCompleted(stepRun);
            parentMap.Remove(stepRun.Id);
        }
 
        Guid GetPlanRunId(Guid runId)
        {
            while (parentMap.TryGetValue(runId, out var runId2))
            {
                runId = runId2;
            }
            return runId;
        }
 
        string GetTmpFileName(TestRun run)
        {
            var id = GetPlanRunId(run.Id);
            var name = $"tmp.artifacts.{id}.zip";
            return name;
        }
        
        public void OnArtifactPublished(TestRun run, Stream artifactStream, string artifactName)
        {
            var fileName = GetTmpFileName(run);
            if (!File.Exists(fileName))
                return; // The file has been finalized.
            
            var rawStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete);
            using var archive = new ZipArchive(rawStream, ZipArchiveMode.Update, false);
            
            var entry = archive.CreateEntry(artifactName);
            entry.FixUnixPermissions();
            using var s2 = entry.Open();
            artifactStream.CopyTo(s2);
            artifactStream.Close();
        }
    }
}