github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/cmd/libsnap-confine-private/classic-test.c (about) 1 /* 2 * Copyright (C) 2017 Canonical Ltd 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 3 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * 16 */ 17 18 #include "classic.h" 19 #include "classic.c" 20 21 #include <glib.h> 22 23 /* restore_os_release is an internal helper for mock_os_release */ 24 static void restore_os_release(gpointer * old) 25 { 26 unlink(os_release); 27 os_release = (const char *)old; 28 } 29 30 /* mock_os_release replaces the presence and contents of /etc/os-release 31 as seen by classic.c. The mocked value may be NULL to have the code refer 32 to an absent file. */ 33 static void mock_os_release(const char *mocked) 34 { 35 const char *old = os_release; 36 if (mocked != NULL) { 37 os_release = "os-release.test"; 38 g_file_set_contents(os_release, mocked, -1, NULL); 39 } else { 40 os_release = "os-release.missing"; 41 } 42 g_test_queue_destroy((GDestroyNotify) restore_os_release, 43 (gpointer) old); 44 } 45 46 /* restore_meta_snap_yaml is an internal helper for mock_meta_snap_yaml */ 47 static void restore_meta_snap_yaml(gpointer * old) 48 { 49 unlink(meta_snap_yaml); 50 meta_snap_yaml = (const char *)old; 51 } 52 53 /* mock_meta_snap_yaml replaces the presence and contents of /meta/snap.yaml 54 as seen by classic.c. The mocked value may be NULL to have the code refer 55 to an absent file. */ 56 static void mock_meta_snap_yaml(const char *mocked) 57 { 58 const char *old = meta_snap_yaml; 59 if (mocked != NULL) { 60 meta_snap_yaml = "snap-yaml.test"; 61 g_file_set_contents(meta_snap_yaml, mocked, -1, NULL); 62 } else { 63 meta_snap_yaml = "snap-yaml.missing"; 64 } 65 g_test_queue_destroy((GDestroyNotify) restore_meta_snap_yaml, 66 (gpointer) old); 67 } 68 69 static const char *os_release_classic = "" 70 "NAME=\"Ubuntu\"\n" 71 "VERSION=\"17.04 (Zesty Zapus)\"\n" "ID=ubuntu\n" "ID_LIKE=debian\n"; 72 73 static void test_is_on_classic(void) 74 { 75 mock_os_release(os_release_classic); 76 mock_meta_snap_yaml(NULL); 77 g_assert_cmpint(sc_classify_distro(), ==, SC_DISTRO_CLASSIC); 78 } 79 80 static const char *os_release_core16 = "" 81 "NAME=\"Ubuntu Core\"\n" "VERSION_ID=\"16\"\n" "ID=ubuntu-core\n"; 82 83 static const char *meta_snap_yaml_core16 = "" 84 "name: core\n" 85 "version: 16-something\n" "type: core\n" "architectures: [amd64]\n"; 86 87 static void test_is_on_core_on16(void) 88 { 89 mock_os_release(os_release_core16); 90 mock_meta_snap_yaml(meta_snap_yaml_core16); 91 g_assert_cmpint(sc_classify_distro(), ==, SC_DISTRO_CORE16); 92 } 93 94 static const char *os_release_core18 = "" 95 "NAME=\"Ubuntu Core\"\n" "VERSION_ID=\"18\"\n" "ID=ubuntu-core\n"; 96 97 static const char *meta_snap_yaml_core18 = "" 98 "name: core18\n" "type: base\n" "architectures: [amd64]\n"; 99 100 static void test_is_on_core_on18(void) 101 { 102 mock_os_release(os_release_core18); 103 mock_meta_snap_yaml(meta_snap_yaml_core18); 104 g_assert_cmpint(sc_classify_distro(), ==, SC_DISTRO_CORE_OTHER); 105 } 106 107 const char *os_release_core20 = "" 108 "NAME=\"Ubuntu Core\"\n" "VERSION_ID=\"20\"\n" "ID=ubuntu-core\n"; 109 110 static const char *meta_snap_yaml_core20 = "" 111 "name: core20\n" "type: base\n" "architectures: [amd64]\n"; 112 113 static void test_is_on_core_on20(void) 114 { 115 mock_os_release(os_release_core20); 116 mock_meta_snap_yaml(meta_snap_yaml_core20); 117 g_assert_cmpint(sc_classify_distro(), ==, SC_DISTRO_CORE_OTHER); 118 } 119 120 static const char *os_release_classic_with_long_line = "" 121 "NAME=\"Ubuntu\"\n" 122 "VERSION=\"17.04 (Zesty Zapus)\"\n" 123 "ID=ubuntu\n" 124 "ID_LIKE=debian\n" 125 "LONG=line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line.line."; 126 127 static void test_is_on_classic_with_long_line(void) 128 { 129 mock_os_release(os_release_classic_with_long_line); 130 mock_meta_snap_yaml(NULL); 131 g_assert_cmpint(sc_classify_distro(), ==, SC_DISTRO_CLASSIC); 132 } 133 134 static const char *os_release_fedora_base = "" 135 "NAME=Fedora\nID=fedora\nVARIANT_ID=snappy\n"; 136 137 static const char *meta_snap_yaml_fedora_base = "" 138 "name: fedora29\n" "type: base\n" "architectures: [amd64]\n"; 139 140 static void test_is_on_fedora_base(void) 141 { 142 mock_os_release(os_release_fedora_base); 143 mock_meta_snap_yaml(meta_snap_yaml_fedora_base); 144 g_assert_cmpint(sc_classify_distro(), ==, SC_DISTRO_CORE_OTHER); 145 } 146 147 static const char *os_release_fedora_ws = "" 148 "NAME=Fedora\nID=fedora\nVARIANT_ID=workstation\n"; 149 150 static void test_is_on_fedora_ws(void) 151 { 152 mock_os_release(os_release_fedora_ws); 153 mock_meta_snap_yaml(NULL); 154 g_assert_cmpint(sc_classify_distro(), ==, SC_DISTRO_CLASSIC); 155 } 156 157 static const char *os_release_custom = "" 158 "NAME=\"Custom Distribution\"\nID=custom\n"; 159 160 static const char *meta_snap_yaml_custom = "" 161 "name: custom\n" 162 "version: rolling\n" 163 "summary: Runtime environment based on Custom Distribution\n" 164 "type: base\n" "architectures: [amd64]\n"; 165 166 static void test_is_on_custom_base(void) 167 { 168 mock_os_release(os_release_custom); 169 170 /* Without /meta/snap.yaml we treat "Custom Distribution" as classic. */ 171 mock_meta_snap_yaml(NULL); 172 g_assert_cmpint(sc_classify_distro(), ==, SC_DISTRO_CLASSIC); 173 174 /* With /meta/snap.yaml we treat it as core instead. */ 175 mock_meta_snap_yaml(meta_snap_yaml_custom); 176 g_assert_cmpint(sc_classify_distro(), ==, SC_DISTRO_CORE_OTHER); 177 } 178 179 static const char *os_release_debian_like_valid = "" 180 "ID=my-fun-distro\n" 181 "ID_LIKE=debian\n"; 182 183 static const char *os_release_debian_like_quoted_valid = "" 184 "ID=my-fun-distro\n" 185 "ID_LIKE=\"debian\"\n"; 186 187 /* actual debian only sets ID=debian */ 188 static const char *os_release_actual_debian_valid = "ID=debian\n"; 189 190 static const char *os_release_invalid = "garbage\n"; 191 192 static void test_is_debian_like(void) 193 { 194 mock_os_release(os_release_debian_like_valid); 195 g_assert_true(sc_is_debian_like()); 196 197 mock_os_release(os_release_debian_like_quoted_valid); 198 g_assert_true(sc_is_debian_like()); 199 200 mock_os_release(os_release_actual_debian_valid); 201 g_assert_true(sc_is_debian_like()); 202 203 mock_os_release(os_release_fedora_ws); 204 g_assert_false(sc_is_debian_like()); 205 206 mock_os_release(os_release_invalid); 207 g_assert_false(sc_is_debian_like()); 208 } 209 210 static void __attribute__((constructor)) init(void) 211 { 212 g_test_add_func("/classic/on-classic", test_is_on_classic); 213 g_test_add_func("/classic/on-classic-with-long-line", 214 test_is_on_classic_with_long_line); 215 g_test_add_func("/classic/on-core-on16", test_is_on_core_on16); 216 g_test_add_func("/classic/on-core-on18", test_is_on_core_on18); 217 g_test_add_func("/classic/on-core-on20", test_is_on_core_on20); 218 g_test_add_func("/classic/on-fedora-base", test_is_on_fedora_base); 219 g_test_add_func("/classic/on-fedora-ws", test_is_on_fedora_ws); 220 g_test_add_func("/classic/on-custom-base", test_is_on_custom_base); 221 g_test_add_func("/classic/is-debian-like", test_is_debian_like); 222 }