Skip to content

Commit 8bc7f07

Browse files
Anandaraju Coimbatore SivarajuAlena Kastsiukavets
authored andcommitted
[Agent 1.1.2] Add unit test to verify unpack_bundle ruby unzip mechanism
Why is this change needed? --------- Prior to this change, we didn't have a way to test the "overwrite" logic in ruby unzip during the fallback mechanism of unpack_bundle method in DownloadBundle command. How does it address the issue? --------- This change adds a unit test to verify if the fallback mechanism works with a debris file in the deployment archive directory.
1 parent 72e0cbd commit 8bc7f07

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
require 'test_helper'
2+
require 'certificate_helper'
3+
require 'stringio'
4+
require 'aws/codedeploy/local/deployer'
5+
6+
class UnpackBundleTest < InstanceAgentTestCase
7+
include InstanceAgent::Plugins::CodeDeployPlugin
8+
def generate_signed_message_for(map)
9+
message = @cert_helper.sign_message(map.to_json)
10+
spec = OpenStruct.new({ :payload => message })
11+
spec.format = "PKCS7/JSON"
12+
13+
return spec
14+
end
15+
16+
# method to create a local source bundle file as zip
17+
def setup_local_file_bundle
18+
@local_file_directory = File.join(@root_dir, @deployment_group_id.to_s, 'LocalFileDirectory')
19+
FileUtils.rm_rf(@local_file_directory)
20+
FileUtils.mkdir_p(@local_file_directory)
21+
22+
input_filenames = %w(file1.txt file2.txt)
23+
input_filenames.each do |filename|
24+
File.open(File.join(@local_file_directory, filename), "w") do |f|
25+
f.write("content of #{filename}")
26+
f.close
27+
end
28+
end
29+
# create the bundle as a local zip file
30+
@local_file_location = File.join(@local_file_directory, "bundle.zip")
31+
Zip::File.open(@local_file_location, Zip::File::CREATE) do |zipfile|
32+
input_filenames.each do |filename|
33+
zipfile.add(filename, File.join(@local_file_directory, filename))
34+
end
35+
end
36+
end
37+
38+
context 'The CodeDeploy Plugin Command Executor' do
39+
setup do
40+
@test_hook_mapping = {
41+
"BeforeBlockTraffic"=>["BeforeBlockTraffic"],
42+
"AfterBlockTraffic"=>["AfterBlockTraffic"],
43+
"ApplicationStop"=>["ApplicationStop"],
44+
"BeforeInstall"=>["BeforeInstall"],
45+
"AfterInstall"=>["AfterInstall"],
46+
"ApplicationStart"=>["ApplicationStart"],
47+
"BeforeAllowTraffic"=>["BeforeAllowTraffic"],
48+
"AfterAllowTraffic"=>["AfterAllowTraffic"],
49+
"ValidateService"=>["ValidateService"]
50+
}
51+
@deploy_control_client = mock
52+
@command_executor = InstanceAgent::Plugins::CodeDeployPlugin::CommandExecutor.new(
53+
{
54+
:deploy_control_client => @deploy_control_client,
55+
:hook_mapping => @test_hook_mapping
56+
})
57+
@aws_region = 'us-east-1'
58+
InstanceMetadata.stubs(:region).returns(@aws_region)
59+
end
60+
61+
context "when executing a command" do
62+
setup do
63+
@cert_helper = CertificateHelper.new
64+
@deployment_id = SecureRandom.uuid
65+
@deployment_group_name = "TestDeploymentGroup"
66+
@application_name = "TestApplicationName"
67+
@deployment_group_id = "foobar"
68+
@command = Aws::CodeDeployCommand::Types::HostCommandInstance.new(
69+
:host_command_identifier => "command-1",
70+
:deployment_execution_id => "test-execution")
71+
@root_dir = '/tmp/codedeploy/'
72+
@deployment_root_dir = File.join(@root_dir, @deployment_group_id.to_s, @deployment_id.to_s)
73+
@archive_root_dir = File.join(@deployment_root_dir, 'deployment-archive')
74+
ProcessManager::Config.config[:root_dir] = @root_dir
75+
end
76+
77+
context "test fallback mechanism in unpack_bundle in DownloadBundle" do
78+
setup do
79+
setup_local_file_bundle
80+
81+
# Create a debris file in the deployment-archive directory to simulate Zip::DestinationFileExistsError.
82+
# This error will be thrown, if the ruby unzip overwrite option is not enabled and when the @archive_root_dir already has the same file.
83+
# With the ruby unzip overwrite fix, the unpack_bundle should succeed even with debris files.
84+
FileUtils.rm_rf(@archive_root_dir)
85+
FileUtils.mkdir_p(@archive_root_dir)
86+
FileUtils.cp(File.join(@local_file_directory, 'file1.txt'), @archive_root_dir)
87+
88+
# We need to avoid removing @archive_root_dir in the actual logic, to avoid debris file to be deleted.
89+
FileUtils.stubs(:rm_rf).with(@archive_root_dir)
90+
# This exception will let the unpack_bundle method to use the rubyzip fallback mechanism
91+
InstanceAgent::LinuxUtil.expects(:extract_zip)
92+
.with(File.join(@deployment_root_dir, 'bundle.tar'), @archive_root_dir)
93+
.raises("Exception: System unzip throws exception with non-zero exit code")
94+
95+
@command.command_name = 'DownloadBundle'
96+
@bundle_type = 'zip'
97+
@deployment_spec = generate_signed_message_for(
98+
{
99+
"DeploymentId" => @deployment_id.to_s,
100+
"DeploymentGroupId" => @deployment_group_id.to_s,
101+
"ApplicationName" => @application_name,
102+
"DeploymentGroupName" => @deployment_group_name,
103+
"Revision" => {
104+
"RevisionType" => "Local File",
105+
"LocalRevision" => {
106+
"Location" => @local_file_location,
107+
"BundleType" => @bundle_type
108+
}
109+
}
110+
})
111+
end
112+
113+
should 'execute DownloadBundle command with debris file in deployment-archive' do
114+
assert_equal 1, (Dir.entries(@archive_root_dir) - [".", ".."]).size
115+
@command_executor.execute_command(@command, @deployment_spec)
116+
assert_equal 2, (Dir.entries(@archive_root_dir) - [".", ".."]).size
117+
end
118+
end
119+
end
120+
end
121+
end

0 commit comments

Comments
 (0)