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  }