1 /* 2 * Copyright (C) 2016 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.os.cts; 18 19 import com.android.compatibility.common.util.ApiLevelUtil; 20 21 import android.os.Build; 22 import android.os.SystemProperties; 23 import android.test.InstrumentationTestCase; 24 import android.util.Log; 25 26 /** 27 * Tests for Security Patch String settings 28 */ 29 public class SecurityPatchTest extends InstrumentationTestCase { 30 31 private static final String TAG = SecurityPatchTest.class.getSimpleName(); 32 private static final String SECURITY_PATCH_ERROR = 33 "security_patch should be in the format \"YYYY-MM-DD\". Found \"%s\""; 34 private static final String SECURITY_PATCH_DATE_ERROR = 35 "security_patch should be \"%d-%02d\" or later. Found \"%s\""; 36 private static final int SECURITY_PATCH_YEAR = 2016; 37 private static final int SECURITY_PATCH_MONTH = 12; 38 39 private boolean mSkipTests = false; 40 private String mVendorSecurityPatch; 41 private String mBuildSecurityPatch; 42 43 @Override 44 protected void setUp() { 45 mSkipTests = (ApiLevelUtil.isBefore(Build.VERSION_CODES.M)); 46 mVendorSecurityPatch = SystemProperties.get("ro.vendor.build.security_patch", ""); 47 mBuildSecurityPatch = Build.VERSION.SECURITY_PATCH; 48 } 49 50 /** Security patch string must exist in M or higher **/ 51 public void testSecurityPatchFound() { 52 if (mSkipTests) { 53 Log.w(TAG, "Skipping M+ Test."); 54 return; 55 } 56 String error = String.format(SECURITY_PATCH_ERROR, mBuildSecurityPatch); 57 assertTrue(error, !mBuildSecurityPatch.isEmpty()); 58 } 59 60 public void testVendorSecurityPatchFound() { 61 if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O) { 62 Log.w(TAG, "Skipping P+ Test"); 63 return; 64 } 65 assertTrue(!mVendorSecurityPatch.isEmpty()); 66 } 67 68 public void testSecurityPatchesFormat() { 69 if (mSkipTests) { 70 Log.w(TAG, "Skipping M+ Test."); 71 return; 72 } 73 String error = String.format(SECURITY_PATCH_ERROR, mBuildSecurityPatch); 74 testSecurityPatchFormat(mBuildSecurityPatch, error); 75 76 if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O) { 77 Log.w(TAG, "Skipping P+ Test"); 78 return; 79 } 80 error = String.format(SECURITY_PATCH_ERROR, mVendorSecurityPatch); 81 testSecurityPatchFormat(mVendorSecurityPatch, error); 82 } 83 84 /** Security patch should be of the form YYYY-MM-DD in M or higher */ 85 private void testSecurityPatchFormat(String patch, String error) { 86 assertEquals(error, 10, patch.length()); 87 assertTrue(error, Character.isDigit(patch.charAt(0))); 88 assertTrue(error, Character.isDigit(patch.charAt(1))); 89 assertTrue(error, Character.isDigit(patch.charAt(2))); 90 assertTrue(error, Character.isDigit(patch.charAt(3))); 91 assertEquals(error, '-', patch.charAt(4)); 92 assertTrue(error, Character.isDigit(patch.charAt(5))); 93 assertTrue(error, Character.isDigit(patch.charAt(6))); 94 assertEquals(error, '-', patch.charAt(7)); 95 assertTrue(error, Character.isDigit(patch.charAt(8))); 96 assertTrue(error, Character.isDigit(patch.charAt(9))); 97 } 98 99 public void testSecurityPatchDates() { 100 if (mSkipTests) { 101 Log.w(TAG, "Skipping M+ Test."); 102 return; 103 } 104 105 String error = String.format(SECURITY_PATCH_DATE_ERROR, 106 SECURITY_PATCH_YEAR, 107 SECURITY_PATCH_MONTH, 108 mBuildSecurityPatch); 109 testSecurityPatchDate(mBuildSecurityPatch, error); 110 111 if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O) { 112 Log.w(TAG, "Skipping P+ Test"); 113 return; 114 } 115 error = String.format(SECURITY_PATCH_DATE_ERROR, 116 SECURITY_PATCH_YEAR, 117 SECURITY_PATCH_MONTH, 118 mVendorSecurityPatch); 119 testSecurityPatchDate(mVendorSecurityPatch, error); 120 } 121 /** Security patch should no older than the month this test was updated in M or higher **/ 122 private void testSecurityPatchDate(String patch, String error) { 123 int declaredYear = 0; 124 int declaredMonth = 0; 125 126 try { 127 declaredYear = Integer.parseInt(patch.substring(0,4)); 128 declaredMonth = Integer.parseInt(patch.substring(5,7)); 129 } catch (Exception e) { 130 assertTrue(error, false); 131 } 132 133 assertTrue(error, declaredYear >= SECURITY_PATCH_YEAR); 134 assertTrue(error, (declaredYear > SECURITY_PATCH_YEAR) || 135 (declaredMonth >= SECURITY_PATCH_MONTH)); 136 } 137 } 138